使用Boost.Python开发Python C++模块时遇导入错误求助
Boost.Python 模块导入问题排查
问题现象
- 初始状态:使用Boost开发Python C++扩展模块,Python执行时抛出
ModuleNotFoundError: No module named 'MyLib',但.py文件与MyLib.dll处于同一目录。 - 修改后状态:将
dll后缀改为pyd,或是把CMake中的add_library(MyLib MODULE MyLib.cpp)替换为PYTHON_ADD_MODULE(MyLib MyLib.cpp),会出现新错误:ImportError: DLL load failed while importing MyLib: 找不到指定的模块。
相关代码
CMake 配置
set(Boost_NO_SYSTEM_PATHS TRUE) set(BOOST_ROOT "C:/local/boost_1_80_0") set(CMAKE_SHARED_MODULE_PREFIX "") find_package(PythonLibs REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS}) link_directories(${PYTHON_LIBRARIES}) find_package(Boost COMPONENTS python310 REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) link_directories(${Boost_LIBRARY_DIRS}) add_library(MyLib MODULE MyLib.cpp) target_link_libraries(MyLib ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
C++ 实现代码
#include <boost/python.hpp> auto* get() { return "Hello from C++"; } BOOST_PYTHON_MODULE(MyLib) { using namespace boost::python; def("get", get); }
Python 测试代码
from MyLib import get get()
解决方案
1. 解决 ModuleNotFoundError
Windows下Python的C扩展模块默认后缀为.pyd,.dll不会被Python识别为可导入的模块。可以直接将编译生成的.dll重命名为.pyd,或者在CMake中添加配置直接生成.pyd后缀的文件:
set(CMAKE_SHARED_MODULE_SUFFIX ".pyd")
2. 解决 ImportError: DLL load failed
该错误通常由依赖库缺失或版本不匹配导致,按以下步骤排查:
- 版本匹配检查:确认Boost.Python的组件版本(
python310)与当前使用的Python解释器版本完全一致(必须是Python 3.10),版本不兼容会直接导致加载失败。 - 依赖库路径配置:将Boost.Python的动态库(如
boost_python310-vcxxx-mt-x64-1_80.dll)和Python的python310.dll放入以下任一位置:- 系统
PATH环境变量包含的目录 - 与
MyLib.pyd、测试.py文件相同的目录
- 系统
- CMake配置优化:
- 移除
link_directories,改用target_link_libraries直接链接依赖,避免路径识别问题 - 确保编译架构(x86/x64)与Python解释器一致(比如Python是64位,编译时必须选择64位工具链)
- 优化后的CMake示例:
- 移除
set(Boost_NO_SYSTEM_PATHS TRUE) set(BOOST_ROOT "C:/local/boost_1_80_0") set(CMAKE_SHARED_MODULE_PREFIX "") set(CMAKE_SHARED_MODULE_SUFFIX ".pyd") # 指定Python版本精确匹配 find_package(PythonLibs 3.10 EXACT REQUIRED) include_directories(${PYTHON_INCLUDE_DIRS}) find_package(Boost COMPONENTS python310 REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) add_library(MyLib MODULE MyLib.cpp) # 使用PRIVATE关键字明确依赖范围 target_link_libraries(MyLib PRIVATE ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
3. C++代码修正
原代码中get()函数存在不必要的缩进,修正后避免编译潜在问题:
#include <boost/python.hpp> const char* get() { return "Hello from C++"; } BOOST_PYTHON_MODULE(MyLib) { using namespace boost::python; def("get", get); }
内容的提问来源于stack exchange,提问作者様 貴方の微笑
相关产品推荐
相关产品推荐

