我创建了一个 C 库
libgac
,然后编写了实现与 ctype
绑定的 Python 模块。
我将 python 模块称为 gazepy
。
我的项目文件结构如下:
pyproject.toml
setup.py
src
gazepy
gac # repo with the C library libgac
gazepy.py # python bindings for the C library libgac
__init__.py # empty file
tests
运行
sudo pip install .
会生成并安装so文件gazepy.cpython-38-x86_64-linux-gnu.so
。
到目前为止一切顺利,但是,如果我想在 python3 shell 中导入库,我会收到以下错误:
ImportError: dynamic module does not define module export function (PyInit_gazepy)
我的
pyproject.toml
文件:
[build-system]
requires = ["setuptools>=61"]
build-backend = "setuptools.build_meta"
[project]
name = "gazepy"
# ...
我的
setup.py
文件:
from setuptools import setup, Extension, find_packages
import subprocess
module_name = "gazepy"
module_path = "src/" + module_name
gac_path = module_path + "/gac"
cglm_path = gac_path + "/cglm"
def main():
setup(
name=module_name,
packages=find_packages(),
ext_modules=[
Extension(module_name, [gac_path + '/src/gac.c'],
include_dirs=[gac_path + '/include', cglm_path + '/include'],
libraries=['m'])
]
)
if __name__ == "__main__":
main()
查看so文件时
gazepy.cpython-38-x86_64-linux-gnu.so
我找不到PyInit_gazepy()
的任何定义:
nm /usr/local/lib/python3.8/dist-packages/gazepy.cpython-38-x86_64-linux-gnu.so | grep PyInit
我在这里缺少什么?
.so
命令时,python 扩展模块(
.pyd
和 .py
文件)比 import
文件具有更高的优先级。
为了让
import gazepy
正确导入你的python文件,你应该将扩展模块的名称module_name
更改为有一个下划线_gazepy
,这样python就不会加载它,那么你应该只加载你的 .so
使用 ctypes。
您正在将 C 库编译为 python 扩展,这是错误的,因为它现在依赖于 python
虽然你的库不是Python扩展模块,但上面的解决方案将起作用,但你应该考虑使用Python的setuptools/setup.py编译和安装C可执行文件所以它不会依赖于Python,不幸的是这比仅仅可移植性更差将此 C 库视为扩展模块,因此如果您关心生成一个干净的库,您应该尝试将其编译为 C 库而不是扩展模块。