macOS下Python3.6 C扩展模块方法无法通过ctypes访问问题咨询
问题原因及解决方法
你犯了两个核心错误,下面逐一说明:
错误1:混淆了CPython扩展和普通C动态库的调用方式
你写的代码是符合CPython扩展规范的模块,不是给ctypes调用的普通动态库:
myfunc的函数签名是固定的CPython扩展方法格式:接收两个PyObject*参数,返回PyObject*,所有参数、返回值都需要CPython解释器完成类型转换,完全不适合用ctypes直接调用- ctypes只适合调用普通C风格、参数和返回值都是C原生类型的函数
错误2:static修饰的函数不会导出到动态库符号表
你代码中myfunc前加了static修饰符,这类函数仅在当前C文件内可见,不会被加入动态库的公开符号表,所以ctypes调用时必然提示找不到符号。
正确操作步骤
你是要开发CPython扩展,不需要用ctypes,按以下步骤修改即可:
- 修改编译命令的输出文件名,CPython扩展需要和模块名匹配:
你的模块初始化函数是PyInit_example,对应的扩展文件名必须为example.so,将第二个编译命令改为:gcc example.o -shared -o example.so -L$PYLIB -lpython3.6m - 直接用Python的标准import语法调用扩展:
替换你的测试代码为以下内容:
运行后就能正常输出结果import example print(example.myfunc())1。
如果你确实想用ctypes调用C代码(可选)
如果你的需求是用ctypes调用普通C函数,而非开发CPython扩展,可以修改C代码为普通C风格,去掉static修饰即可:
long myfunc(const char* input) { return 1; }
这种场景下才适合用你原来的ctypes测试代码调用。
内容的提问来源于stack exchange,提问作者broken.eggshell
相关产品推荐
相关产品推荐

