【问题标题】:Embedding Python -- loading already loaded module嵌入 Python -- 加载已加载的模块
【发布时间】:2023-03-25 23:55:02
【问题描述】:

我正在尝试将 wxPython 嵌入到 wxWidgets 应用程序中,但出现以下错误:

../src/common/object.cpp(251): assert "classTable->Get(m_className) == NULL" 在 Register() 中失败:RTTI 表中已经存在类 "wxCommandEvent" - 你使用过 IMPLEMENT_DYNAMIC_CLASS( ) 多次或链接某个目标文件两次)?

我已经追踪到: wxPyCoreAPIPtr = (wxPyCoreAPI*)PyCObject_Import("wx.core", "_wxPyCoreAPI");

所以我猜测这是失败的,因为它试图 dlopen 一个已经加载的 .so(C 和 Python 代码都需要的核心 wxwidgets 库)。我可以通过 dlopen 的 RTLD_NOLOAD 标志获取打开的 .so 的句柄。

有什么方法可以将该句柄提供给 Python 并告诉它将该句柄“加载”到解释器的上下文中?

编辑:刚刚注意到,使用 wxWidgets origin/WX_3_0_BRANCH、Python 2.7、wxPython origin/master 在 wxPython 中的“嵌入式”示例中可以重现此问题。

另外,它可能特定于 gtk3 配置...当我使用 gtk2 编译时,它似乎可以正常工作。

【问题讨论】:

    标签: python wxpython wxwidgets embedding dlopen


    【解决方案1】:

    问题是 wxPython 是用 gtk2 标志编译的,wxWidgets gtk3。

    您可以在 gdb 中通过在断言附近转储其中一个符号来确定这一点:

    信息符号 __static_initialization_and_destruction_0 /usr/lib/libwx_gtk2u_core-3.0.so.0 的 .text 部分中的 __static_initialization_and_destruction_0(int, int)

    要重新构建 wxPython,您需要手动将构建目录移动到其他位置(或者重新安装似乎可以工作,但实际上不会重新构建任何东西)。

    然后使用:python setup.py build_ext WXPORT=gtk3

    您应该看到正在针对 gtk3 构建 .so 文件:

    c++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-Bsymbolic-functions -Wl,-z,relro -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -D_FORTIFY_SOURCE=2 -g -fstack-protector --param=ssp-buffer-size=4 -Wformat -Werror=format-security build/temp.linux-x86_64-2.7/src/gtk/wizard_wrap.o -L/usr/X11R6/lib -lwx_gtk3u_xrc-3.0 -lwx_gtk3u_html-3.0 -lwx_gtk3u_qa-3.0 -lwx_gtk3u_adv-3.0 -lwx_gtk3u_core-3.0 -lwx_baseu_xml-3.0 -lwx_baseu_net-3.0 -lwx_baseu-8_6 build-/lib 2.7/wx/_wizard.so -pthread

    (注意 wx_gtk3u_xxx 文件,vs: wx_gtk2u_xxx)

    然后:

    python setup.py install WXPORT=gtk3

    有效!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-04-02
      • 1970-01-01
      • 2017-03-16
      • 2012-12-10
      • 1970-01-01
      • 2016-11-05
      • 1970-01-01
      • 2011-01-02
      相关资源
      最近更新 更多