使用PyBind11生成Python模块遇ImportError:无法动态加载可执行文件
问题根源与解决方案
你的核心问题是编译时生成的是可执行文件而非Python可加载的动态库,同时代码中的main函数会干扰动态库的生成逻辑,导致加载错误。以下是具体修复步骤:
1. 移除代码中的main函数
PyBind11模块是作为动态库被Python加载的,不需要main函数——它会让编译器默认生成可执行文件而非动态库。修改后的pymodule.cpp如下:
#include "otherfile.h" #include <iostream> #include <pybind11/pybind11.h> #include <pybind11/numpy.h> void fn() { std::cout << "fn works" << std::endl; fn2(); // from otherfile.cpp } PYBIND11_MODULE(test, m) { m.doc() = "Test"; m.def("fn", &fn); }
2. 修改Makefile,生成动态库
关键是添加-shared选项(强制生成动态共享库),同时调整编译参数的顺序(链接参数放在源文件之后)。修改后的Makefile:
#!/bin/bash INC=$(shell pybind11-config --includes) -I$(shell pwd)/include FLAGS=-fPIC -shared # 添加-shared是核心 default: test_module test_module: g++ $(FLAGS) $(INC) pymodule.cpp otherfile.cpp $(shell python3-config --ldflags) -o test$(shell python3-config --extension-suffix)
关键参数说明
-shared:告诉g++生成动态库而非可执行文件,直接解决"cannot dynamically load executable"错误- 移除了手动添加的
-lpython3.10,因为python3-config --ldflags已经包含了正确的Python库链接参数,避免版本不匹配问题 - 链接参数放在源文件之后,符合g++的依赖解析顺序,确保库能被正确找到
验证修复
- 执行
make编译生成模块 - 运行
test.py,此时应该能正常导入模块并调用fn()函数
内容的提问来源于stack exchange,提问作者Bemused
相关产品推荐
相关产品推荐

