原本我在一个使用pybind11嵌入Anaconda Python解释器的大项目中遇到了这个错误。我通过一个简单的最小示例可以重现出这个错误。
当我运行我的可执行文件(嵌入Python)时,我会得到这个错误:
Traceback (most recent call last):
File "<string>", line 3, in <module>
File "/app/Python-3.8.2-build/lib/python3.8/struct.py", line 13, in <module>
from _struct import *
ImportError: /app/Python-3.8.2-build/lib/python3.8/lib-dynload/_struct.cpython-38-x86_64-linux-gnu.so: undefined symbol: PyByteArray_Type
首先,我从源代码构建了Python-3.8.2。然后我从以下C代码编译了一个可执行文件:
#include <Python.h>
int main(int argc, char *argv[])
{
Py_Initialize();
PyRun_SimpleString("import struct");
if (Py_FinalizeEx() < 0) {
exit(120);
}
return 0;
}
使用以下命令:
gcc -o execpy execpy.c \
-I/app/Python-3.8.2-build/include/python3.8 \
-Wno-unused-result -Wsign-compare -DNDEBUG -g -fwrapv -O3 \
-L/app/Python-3.8.2-build/lib -lcrypt -lpthread -ldl -lutil -lm \
/app/Python-3.8.2/libpython3.8.a
然后只需执行./execpy
即可得到上面的错误...有什么想法吗?
编辑: 在这个例子中,我想像Python解释器一样静态链接libpython
,不依赖于任何libpython.so
。
编辑: _struct.*.so
似乎没有与链接的libpython
相关的依赖项(这对我的标准anaconda Python解释器也是如此):
$ ldd /app/Python-3.8.2-build/lib/python3.8/lib-dynload/_struct.cpython-38-x86_64-linux-gnu.so
linux-vdso.so.1 => (0x00007fff32bf0000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f71a5634000)
libc.so.6 => /lib64/libc.so.6 (0x00007f71a5266000)
/lib64/ld-linux-x86-64.so.2 (0x00007f71a5a5c000)
我还在另一台机器上检查了系统Python解释器的_struct.*.so
文件,它也有这个文件:
linux-vdso.so.1 => (0x00007ffe2b3d9000)
libpython3.6m.so.1.0 => /lib64/libpython3.6m.so.1.0 (0x00007febe24fd000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007febe22e1000)
libc.so.6 => /lib64/libc.so.6 (0x00007febe1f13000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007febe1d0f000)
libutil.so.1 => /lib64/libutil.so.1 (0x00007febe1b0c000)
libm.so.6 => /lib64/libm.so.6 (0x00007febe180a000)
/lib64/ld-linux-x86-64.so.2 (0x00007febe2c30000)
ldd /app/Python-3.8.2-build/lib/python3.8/lib-dynload/_struct.cpython-38-x86_64-linux-gnu.so
会输出什么?它是否加载了不同的 libpython3.8? - Botje