pybind11极简示例编译后Python导入报ImportError问题求助
问题根因
报错ImportError: dynamic module does not define module export function (PyInit_relativity)和你引入pybind11的方式(find_package系统查找/add_subdirectory内嵌源码)无关,核心错误是C++代码中定义的pybind11模块名,和编译输出的动态库文件名不匹配。
Python导入C扩展模块时,会按照模块名查找对应的初始化函数PyInit_<模块名>:
- 你C++代码里写的是
PYBIND11_MODULE(example, m),编译后只会导出PyInit_example初始化函数 - 但你CMake中指定生成的模块名是项目名
relativity,最终输出relativity.so - 执行
import relativity时Python会查找PyInit_relativity函数,找不到就抛出你看到的报错。
你把pybind11源码克隆到项目里重新编译还是报同样的错,就是因为这个命名不匹配的问题根本没改,和pybind11的引入路径没关系。
修复方案
两种方案选一个即可,保证两处名称完全一致:
- 修改C++代码的模块定义,和输出库名对齐
把main.cpp里的模块定义宏第一个参数改成relativity:
重新执行cmake和make编译,生成的PYBIND11_MODULE(relativity, m) { m.doc() = "pybind11 example plugin"; m.def("add", &add, "A function that adds two numbers"); }relativity.so就可以正常在Python中导入。 - 修改CMake配置的模块名,和C++中定义的模块名对齐
如果你想保留模块名example,就把CMakeLists.txt里的pybind11_add_module第一个参数改成example:
编译后会生成pybind11_add_module(example ${SOURCES})example.so,在Python中执行import example即可正常使用。
补充说明
你不想把pybind11仓库复制到项目目录的用法是完全官方支持的:只要提前通过pip、系统包管理器等方式全局安装pybind11,find_package(pybind11)就可以正常找到依赖,不需要强制内嵌pybind11源码。
内容的提问来源于stack exchange,提问作者catmousedog
相关产品推荐
相关产品推荐

