使用Python C API时出现ImportError
我有一个程序,它可以加载 .so
共享对象来扩展功能。这些扩展是用 C++ 编写的,但我想使用一些已经写好的 Python 函数,所以我使用了 Python C API。到目前为止,一切都很好。
调用 Python 函数运行得很顺利,但如果我在 Python 中导入 spidev 模块,就会出现以下错误:
import spidev
ImportError: /usr/local/lib/python2.7/dist-packages/spidev.so: undefined symbol: _Py_ZeroStruct
Segmentation fault
如果我导入标准的 Python 模块(比如 sys、os、argparse 等),就没有问题。
那可能是什么问题呢?
补充说明:我知道我可以直接在 C++ 中使用 spidev,但我想尽量重用现有的 Python 代码。
更新:
正如 @BrianCain 和 @qarma 指出的,这可能是与 libpython
相关的依赖问题,所以我包括了 ldd
的输出:
$ ldd myextension.so
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f89000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6f5f000)
libdl.so.2 => /lib/arm-linux-gnueabihf/libdl.so.2 (0xb6f54000)
libutil.so.1 => /lib/arm-linux-gnueabihf/libutil.so.1 (0xb6f49000)
libm.so.6 => /lib/arm-linux-gnueabihf/libm.so.6 (0xb6ed8000)
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0xb6c47000)
libgcc_s.so.1 => /lib/arm-linux-gnueabihf/libgcc_s.so.1 (0xb6c1f000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6af0000)
/lib/ld-linux-armhf.so.3 (0xb6fa2000)
libz.so.1 => /lib/arm-linux-gnueabihf/libz.so.1 (0xb6ad2000)
$ ldd /usr/local/lib/python2.7/dist-packages/spidev.so
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6ed3000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6ea9000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6d7a000)
/lib/ld-linux-armhf.so.3 (0xb6eed000)
更新2:
spidev 安装的输出。
$ sudo pip install spidev
Downloading/unpacking spidev
Downloading spidev-2.0.tar.gz
Running setup.py egg_info for package spidev
Installing collected packages: spidev
Running setup.py install for spidev
building 'spidev' extension
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I/usr/src/linux/include -I/usr/include/python2.7 -c spidev_module.c -o build/temp.linux-armv6l-2.7/spidev_module.o
gcc -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions -Wl,-z,relro build/temp.linux-armv6l-2.7/spidev_module.o -o build/lib.linux-armv6l-2.7/spidev.so
Successfully installed spidev
Cleaning up...
$ ldd /usr/local/lib/python2.7/dist-packages/spidev.so
/usr/lib/arm-linux-gnueabihf/libcofi_rpi.so (0xb6f97000)
libpthread.so.0 => /lib/arm-linux-gnueabihf/libpthread.so.0 (0xb6f6d000)
libc.so.6 => /lib/arm-linux-gnueabihf/libc.so.6 (0xb6e3e000)
/lib/ld-linux-armhf.so.3 (0xb6fb1000)
仍然没有依赖于 libpython
...
1 个回答
0
我怀疑你的 spidev.so
是用错误版本的 Python 编译的,或者编译得不好。
请在你的 Python 和这个库上运行 ldd
命令。如果有不匹配的地方,那就麻烦了!如果没有,那就需要更深入地检查了。
这里是它应该如何工作的:
(test)[dima@bmg py-spidev]$ python setup.py build
(test)[dima@bmg py-spidev]$ ldd build/lib.linux-x86_64-2.7/spidev.so
linux-vdso.so.1 (0x00007fffbadfe000)
libpython2.7.so.1.0 => /usr/lib/libpython2.7.so.1.0 (0x00007f42c9659000)
libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007f42c943c000)
libc.so.6 => /usr/lib/libc.so.6 (0x00007f42c9094000)
libdl.so.2 => /usr/lib/libdl.so.2 (0x00007f42c8e8f000)
libutil.so.1 => /usr/lib/libutil.so.1 (0x00007f42c8c8c000)
libm.so.6 => /usr/lib/libm.so.6 (0x00007f42c898b000)
/usr/lib64/ld-linux-x86-64.so.2 (0x00007f42c9c50000)
(test)[dima@bmg py-spidev]$ python setup.py install
(test)[dima@bmg py-spidev]$ python
>>> import spidev
>>> dir(spidev)
['SpiDev', '__doc__', '__file__', '__name__', '__package__']
注意,它应该链接到某个 libpython2.x.so.y.z
文件。
也许你的目标 Python(如果是交叉编译的话)缺少 python-config
呢?