使用 ctypes 创建一个 python 模块
Posted
技术标签:
【中文标题】使用 ctypes 创建一个 python 模块【英文标题】:creating a python module using ctypes 【发布时间】:2021-03-29 01:34:05 【问题描述】:我有一个只有两个函数的 C 库:char *foo_decode(const char*)
和 const char *foo_version()
。
我现在想创建一个允许调用这两个函数的 python 模块。
C 库编译成foo.so
。
这是我的python模块文件:
$ cat foo.py
import ctypes as ct
_lib = ct.cdll.LoadLibrary("./foo.so")
_lib.foo_decode.argtypes = [ct.c_char_p]
_lib.foo_decode.restype = ct.c_char_p
_lib.foo_version.argtypes = []
_lib.foo_version.restype = ct.c_char_p
def decode(fooText):
return _lib.foo_decode(fooText.encode('utf8')).decode('utf-8')
def version():
return _lib.foo_version().decode('utf-8')
我关注了this tutorial。
当我启动一个 python3 解释器并手动执行它时。一切正常。 我可以调用这些函数并得到预期的结果。
但是当我导入我的模块文件 (import foo
) 时,我收到错误 ImportError: dynamic module does not define module export function (PyInit_foo)
。
发生了什么,我应该怎么做才能解决这个问题?
我的目标是生成一个可通过 pip install 下载的包。我在正确的轨道上吗?我不想要***,因为代码很小并且没有依赖关系。因此我应该快速编译并且应该非常便携。
【问题讨论】:
顺便说一句,global
语句完全没有必要,您应该删除它们。
@juanpa.arrivillaga 我删除了global _lib
。谢谢
在这种情况下,动态模块名称以下划线开头:_foo.so。
【参考方案1】:
您有一个共享库foo.so
和一个模块foo.py
。当 Python 执行 import foo
时,它只加载其中一个;在你的情况下是foo.so
;但foo.so
不是 Python 模块,因此会出现错误。
将您的 foo.py
重命名为 foo_wrapper.py
之类的不同名称,然后尝试 import foo_wrapper
。
【讨论】:
这行得通。非常感谢。生成 .so 文件时我有点快。通常,.so 文件被命名为libfoo.so
。这样可以避免混淆。我更喜欢调用模块foo
。
当然,所有名称都由您决定。只是不要将 Python 的导入与相同的名称混淆。 :-)以上是关于使用 ctypes 创建一个 python 模块的主要内容,如果未能解决你的问题,请参考以下文章
使用 Python 的 ctypes 调用涉及自定义类型的函数
[转]python使用ctypes模块调用windowsapi获取系统版本