6

我正在开发一个调用 python 脚本的 C 共享库。当我运行应用程序时,我收到此错误:

Traceback (most recent call last):
  File "/home/ubuntu/galaxy-es/lib/galaxy/earthsystem/gridftp_security/gridftp_acl_plugin.py", line 2, in <module>
    import galaxy.eggs
  File "/home/ubuntu/galaxy-es/lib/galaxy/eggs/__init__.py", line 5, in <module>
    import os, sys, shutil, glob, urllib, urllib2, ConfigParser, HTMLParser, zipimport, zipfile
  File "/usr/lib/python2.7/zipfile.py", line 6, in <module>
    import io
  File "/usr/lib/python2.7/io.py", line 60, in <module>
    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
>>> 

在编译库期间,我使用了这里建议的编译器选项: Embedding python in C, undefined symbol: PyExc_ImportError 此外,我还添加了从 python-config --includes|--libs|-- 获得的编译器选项cflags|--ldflags

在这里您可以找到库http://pastebin.com/348rhBjM的 makefile 的日志

非常感谢,任何帮助将不胜感激。

4

3 回答 3

6

@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 应该是不必要的。

我正在使用带有 Python 版本 2.5.2-2ubuntu4.1 的 Ubuntu 8.04。

我所要做的就是添加一行代码:

// new line of code
void*const libpython_handle = dlopen("libpython2.6.so", RTLD_LAZY | RTLD_GLOBAL);

PyInitialize();

ps 我在 CentOS-6 上。

pps MyPyInitialize()被包装在一个类中,因此dlopen()/PyInitialize()在构造函数中完成,dlclose()/PyFinalize()在析构函数中完成。

于 2018-05-23T13:32:42.417 回答
3

我找到了解决方案。也许对其他人有用。这是这里写的 python 的错误http://mail.python.org/pipermail/new-bugs-announce/2008-November/003322.html 我使用了这里发布的解决方案http://www.cilogon.org /gsi-c-authz

于 2012-08-07T13:58:54.133 回答
0

我使用这样的解决方法:从 lib-dynload 目录显式链接插件(很简单,然后在代码中显式 dlopen)。datetime.so 示例:

制作:

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
于 2012-12-24T09:13:54.250 回答