未定义符号:在 C 中嵌入 Python 时出现 PyExc_ImportError
Posted
技术标签:
【中文标题】未定义符号:在 C 中嵌入 Python 时出现 PyExc_ImportError【英文标题】:undefined symbol: PyExc_ImportError when embedding Python in C 【发布时间】:2012-08-04 06:55:00 【问题描述】:我正在开发一个调用 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日志
非常感谢,任何帮助将不胜感激。
【问题讨论】:
命令应该是这样的:pastebin.com/jSqSnBj5,而不是pastebin.com/348rhBjM,你可以找到整个make log。 你有很多警告,你真的应该检查一下!乍一看,最严重的似乎是:globus_gfs_acl_vm.c:260:33: warning: passing argument 2 of ‘snprintf’ makes integer from pointer without a cast
。虽然可能与您的问题无关,但您应该真的尝试尽可能多地修复警告!
@rdil2503:请将答案标记为已接受,最好是 Trevor 的答案。
【参考方案1】:
我找到了解决方案。也许对其他人有用。 这是这里写的python的一个错误http://mail.python.org/pipermail/new-bugs-announce/2008-November/003322.html 我已经使用了这里发布的解决方案http://www.cilogon.org/gsi-c-authz
【讨论】:
第一个链接mail.python.org/pipermail/new-bugs-announce/2008-November/…提供了一个简洁易懂的问题陈述和解决方案。 第二个链接cilogon.org/gsi-c-authz 很长而且曲折,是为一个特定的应用程序编写的我找不到任何看起来像通用解决方案的东西。 肯定会选择第一个链接【参考方案2】:我使用这样的解决方法:从 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
【讨论】:
【参考方案3】:@user1515248 solution 是一个仅限链接的解决方案,即discouraged。我正在写这个答案以扩展他提供的链接并提供更充实的答案(这也支持他提供的链接)。
链接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();
附言 我在 CentOS-6 上。
p.p.s.
我的PyInitialize()
被包装在一个类中,所以dlopen()
/PyInitialize()
在构造函数中完成,dlclose()
/PyFinalize()
在析构函数中完成。
【讨论】:
别忘了说一定要包含#include以上是关于未定义符号:在 C 中嵌入 Python 时出现 PyExc_ImportError的主要内容,如果未能解决你的问题,请参考以下文章
在 C 中嵌入 python,未定义符号:PyExc_ImportError
在 macOS Catalina 上链接 OpenMP 时出现“未定义符号 _main”
在 Xcode 4 下构建 PhoneGap 时出现未定义符号错误?