我的情况是我有一个可执行文件(
main.c
)动态加载共享对象的(
py_plugin.c
)它又链接到python。
但是,当python插件尝试导入依赖项为
不
链接到libpython时,我发现以下错误:
ImportError: /usr/lib/python2.7/lib-dynload/bz2.x86_64-linux-gnu.so: undefined symbol: PyExc_SystemError
据我推断,这意味着图书馆
bz2.x86_64-linux-gnu.so
无法访问python符号。
请注意,该错误特定于“bz2”包,因为我使用问题末尾的最小工作示例强制它浮出水面。在那里,我显式导入“bz2”,加载库
bz2.x86\u 64-linux-gnu。所以
,位于python插件内部(
py\u插件。c
).
查看依赖关系,我验证:
-
图书馆
bz2.x86\u 64-linux-gnu。所以
是
不
链接到python
usr@cmptr $ ldd /usr/lib/python2.7/lib-dynload/bz2.x86_64-linux-gnu.so
linux-vdso.so.1 => (0x00007ffd511fb000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f8c63a0a000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f8c6362a000)
libbz2.so.1.0 => /lib/x86_64-linux-gnu/libbz2.so.1.0 (0x00007f8c6341a000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8c63e33000)
-
但是我的python插件
是
:
usr@cmptr $ ldd py_plugin.so
linux-vdso.so.1 => (0x00007ffc1ef5c000)
libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007f56ac01c000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f56abc3c000)
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007f56aba1d000)
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007f56ab800000)
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007f56ab5fc000)
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007f56ab3f8000)
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007f56ab0a2000)
/lib64/ld-linux-x86-64.so.2 (0x00007f56ac79a000)
我的问题如下:
-
问题本身很明显,但为什么当我的插件明确链接到libpython时,python符号不可用?
-
如果我可以的话,有人知道如何解决这个问题吗
不
将python链接到主可执行文件(它是预编译的二进制文件)?
从…起
this e-mail thread
我理解错误的根源可能是python发行理念的不同(我运行的是基于Ubuntu的发行版)。这
bug report
还强调了这个问题。
示例生成错误
生成libs/exec
gcc $(pkg-config --cflags python) -shared -o py_plugin.so py_plugin.c $(pkg-config --libs python)
gcc -o main main.c -lltdl
我的系统上pkg config的输入为:
pkg-config --cflags python
-I/usr/include/python2.7 -I/usr/include/x86_64-linux-gnu/python2.7
pkg-config --libs python
-lpython
文件:
主要的c
#include <ltdl.h>
#include <stdio.h>
typedef int(*dyn_fptr)();
int main()
{
if(lt_dlinit()) {
return -1;
}
lt_dlhandle handle = lt_dlopen("./py_plugin.so");
dyn_fptr func = (dyn_fptr)lt_dlsym(handle, "func");
int a = func(); // <----------------------------------- Call "func" in py_plugin
lt_dlclose(handle);
return 0;
}
文件:
py\u插件。c
#include <Python.h>
int func()
{
Py_Initialize();
PyObject *pName = PyString_FromString("bz2");
PyObject *pModule = PyImport_Import(pName); // <--------------------- ERROR
Py_DECREF(pName);
if(!pModule) {
PyErr_Print();
}
Py_Finalize();
return 0;
}