Linux下导入含ctypes加载.so的.py文件时出现PyInit_a错误
解决import普通动态库时出现“dynamic module does not define module export function (PyInit_a)”的问题
错误原因
Python在导入后缀为.so的文件时,默认会将其识别为Python C扩展模块,这类模块必须导出PyInit_<模块名>(Python3)或init<模块名>(Python2)初始化函数。但你的a.so是普通的C兼容动态库,没有实现该导出函数,因此触发报错。
解决方案
方案1:修改动态库文件名(最简单)
将编译生成的动态库改名,避免与Python模块名冲突:
- 编译命令调整为:
g++ -shared -fPIC -o liba.so a.cpp - 修改
a.py中的加载路径:import ctypes lib = ctypes.cdll.LoadLibrary('./liba.so') # 调用函数f lib.f() - 此时
b.py中执行import a会正确导入a.py文件,而非同名的.so库,问题解决。
方案2:调整Python模块的导入逻辑
如果不想修改动态库名称,可通过以下方式避免Python误加载.so文件:
- 在
a.py中明确指定动态库的绝对加载路径,确保加载的是正确的文件:import ctypes import os # 获取当前脚本所在目录 lib_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'a.so') lib = ctypes.cdll.LoadLibrary(lib_path) - 若
b.py与a.py、a.so同级,可通过调整sys.path优先导入Python文件:# b.py中 import sys sys.path.insert(0, './') # 确保当前目录优先导入Python模块 import a
方案3:将动态库封装为标准Python扩展模块
如果需要更规范的Python模块调用方式,可将普通动态库改造为Python C扩展:
- 安装Python开发依赖(以Debian/Ubuntu为例):
sudo apt-get install python3-dev - 修改
a.cpp,添加Python扩展的初始化代码:#include <Python.h> extern "C" { // 原有的函数f void f() { // 你的函数实现 } // 定义模块方法列表 static PyMethodDef AModuleMethods[] = { {"f", (PyCFunction)f, METH_NOARGS, "Execute function f"}, {NULL, NULL, 0, NULL} // 方法列表结束标记 }; // 定义模块结构体 static struct PyModuleDef AModuleDef = { PyModuleDef_HEAD_INIT, "a", // 模块名 "A sample module", // 模块文档 -1, // 模块状态大小(-1表示全局状态) AModuleMethods }; // 模块初始化函数(必须导出) PyMODINIT_FUNC PyInit_a(void) { return PyModule_Create(&AModuleDef); } } - 使用Python提供的编译参数编译:
g++ -shared -fPIC -o a.so $(python3-config --cflags --ldflags) a.cpp - 此时
b.py中可直接导入并调用:import a a.f()
内容的提问来源于stack exchange,提问作者Sasha
相关产品推荐
相关产品推荐

