Get(m_clas..." /> Get(m_clas..." /> Get(m_clas..."/>

Embedding Python -- loading already loaded module

308 views Asked by At

I am trying to embed wxPython in a wxWidgets application and I get the following error:

../src/common/object.cpp(251): assert "classTable->Get(m_className) == NULL" failed in Register(): Class "wxCommandEvent" already in RTTI table - have you used IMPLEMENT_DYNAMIC_CLASS() multiple times or linked some object file twice)?

I've traced this up to: wxPyCoreAPIPtr = (wxPyCoreAPI*)PyCObject_Import("wx.core", "_wxPyCoreAPI");

So I'm guessing that this is failing because its trying to dlopen a .so that has already been loaded (the core wxwidgets library that is needed both by C and Python code). I can get the handle to the opened .so via dlopen's RTLD_NOLOAD flag.

Is there any way to give that handle to Python and tell it to "load" that handle into the interpreter's context?

Edit: just noticed, this problem is reproducible in the "embedded" sample in wxPython, using wxWidgets origin/WX_3_0_BRANCH, Python 2.7, wxPython origin/master.

Also, it may be specific to gtk3 configurations... it seemed to be working when I compiled with gtk2.

1

There are 1 answers

0
Andrew Stone On

The problem is that wxPython is compiled with gtk2 flag, wxWidgets gtk3.

You can determine this in gdb by dumping one of the symbols near the assertion:

info symbol __static_initialization_and_destruction_0 __static_initialization_and_destruction_0(int, int) in section .text of /usr/lib/libwx_gtk2u_core-3.0.so.0

To rebuild wxPython, you need to manually move the build directory somewhere else (or the reinstall will seem to work but in fact won't rebuild anything).

then use: python setup.py build_ext WXPORT=gtk3

You should see that .so files are being build against gtk3:

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-3.0 -o build/lib.linux-x86_64-2.7/wx/_wizard.so -pthread

(note the wx_gtk3u_xxx files, vs: wx_gtk2u_xxx)

then:

python setup.py install WXPORT=gtk3

works!