未定义的符号:在C中嵌入Python时的PyExc_ImportError
我正在开发一个调用python脚本的C共享库。 当我运行应用程序时,我收到此错误:
Traceback (most recent call last): File "/home/ubuntu/galaxy-es/lib/galaxy/earthsystem/gridftp_security/gridftp_acl_plugin.py", line 2, in import galaxy.eggs File "/home/ubuntu/galaxy-es/lib/galaxy/eggs/__init__.py", line 5, in import os, sys, shutil, glob, urllib, urllib2, ConfigParser, HTMLParser, zipimport, zipfile File "/usr/lib/python2.7/zipfile.py", line 6, in import io File "/usr/lib/python2.7/io.py", line 60, in import _io ImportError: /usr/lib/python2.7/lib-dynload/_io.so: undefined symbol: PyExc_ImportError
如果我尝试从控制台导入模块io工作正常:
Python 2.7.1+ (r271:86832, Apr 11 2011, 18:13:53) [GCC 4.5.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import galaxy.eggs >>>
在编译库的过程中,我使用了这个编译器选项,如下所示: 在C中嵌入python,未定义的符号:PyExc_ImportError此外,我还添加了从python-config获得的编译器选项–includes | –libs | – CFLAGS | –ldflags
在这里,您可以找到库http://pastebin.com/348rhBjM的makefile日志
非常感谢,任何帮助都会被贬低。
我找到了解决方案。 也许对其他人有用。 这是写在这里的python的一个bug http://mail.python.org/pipermail/new-bugs-announce/2008-November/003322.html我用过这里发布的解决方案http://www.cilogon.org / GSI-C-AuthZ的
我使用这样的解决方法:从lib-dynload目录显式链接插件(简单地说,然后在代码中显式dlopen)。 datetime.so示例:
cmake的:
SET ( CMAKE_SHARED_LINKER_FLAGS "/usr/lib/python2.7/lib-dynload/datetime.so" )
或者只是将/usr/lib/python2.7/lib-dynload/datetime.so作为链接器参数添加到命令行中的gcc:
g++ -shared -o libfoo.so foo.o -lbar -lzab /usr/lib/python2.7/lib-dynload/datetime.so
@ user1515248解决方案是不支持链接的解决方案。 我正在写这个答案,以扩展他给出的链接,并提供一个更加充实的答案(这也支持他给出的链接)。
该链接https://mail.python.org/pipermail/new-bugs-announce/2008-November/003322.html说:
我得到了以下解决方法:在mylib.c中,在
PyInitialize()
之前我可以调用dlopen("libpython2.5.so", RTLD_LAZY | RTLD_GLOBAL)
;这有效,但我相信lib-dynload / *。so应该依赖于libpython2.5.so.1所以这个hack不应该是必需的。
我正在使用Ubuntu 8.04和Python版本2.5.2-2ubuntu4.1。
我所要做的就是添加一行代码:
// new line of code void*const libpython_handle = dlopen("libpython2.6.so", RTLD_LAZY | RTLD_GLOBAL); PyInitialize();
ps我在CentOS-6上。
pps我的PyInitialize()
包装在一个类中,所以dlopen()
/ PyInitialize()
在构造函数中完成, dlclose()
/ PyFinalize()
在析构函数中完成。