python - 使用 Python C API 时出现 ImportError

标签 python python-c-api

我有一个二进制文件,可以加载 .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...

最佳答案

我怀疑你的 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

关于python - 使用 Python C API 时出现 ImportError,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23366078/

相关文章:

python - 在Python中比较两个元组的部分值

python - 是否有一个 NumPy C API 函数可以重置布局标志?

Python:PyDateTime_FromTimestamp 的用法

python - python 中的 C 代码和在 C 代码中复制数组

python - 在 C 中调用 Python-3 函数

python - python 将骰子的两个结果相加

python - 我的另一个 python 导入问题

python - 在 python 中垂直打印行(不是列表)

python - 对数据框列内列表的值进行排序

python - 关于如何使用 SWIG 为 python 做 c 包装的疑问