能否使用C++Builder与CMake创建Python模块?
我之前在给Python写扩展模块用C++Builder的bcc32编译时,也踩过这个一模一样的坑!折腾了好一阵才搞明白问题出在哪,现在把解决方案整理给你:
问题核心原因
- C++Builder的32位
bcc32编译器默认用cdecl调用约定,而且会给所有导出函数自动加下划线前缀——比如你写的PyInitialize_mymodule会被编译成_PyInitialize_mymodule - 但Python加载
.pyd模块时,是严格按照PyInitialize_<模块名>这个格式找入口函数的,多了个下划线直接就认不出来,自然加载失败
可行的解决方案
1. 用CMake构建时的配置
如果你的项目用CMake管理,直接在CMakeLists.txt里加针对bcc32的特殊配置,就能让编译器生成符合要求的导出函数:
# 检测到Borland/bcc32编译器时调整选项 if(CMAKE_CXX_COMPILER_ID MATCHES "Borland") # -Vx选项会移除cdecl调用约定带来的下划线前缀 set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Vx") # 定义DLL相关宏,确保导出正确 add_definitions(-D_USRDLL -D_WINDLL) endif()
同时,在你的模块入口函数声明里,要显式指定调用约定,避免编译器乱改:
extern "C" __declspec(dllexport) PyObject* __cdecl PyInitialize_mymodule(void) { // 这里写你的模块初始化逻辑 }
2. 直接用C++Builder项目的.def文件方法
如果不用CMake,直接在C++Builder里建项目的话,搞个模块定义文件(.def)就能强制指定导出函数名:
LIBRARY mymodule # 这里换成你的模块名 EXPORTS PyInitialize_mymodule @1 # 显式导出这个函数,不带下划线
把这个.def文件添加到你的C++Builder项目里,编译器就会严格按照你写的名字导出,不会自动加下划线了。
3. 调整C++Builder的编译器可视化设置
嫌改代码或配置文件麻烦的话,直接在项目设置里改:
- 打开项目的Options(选项)窗口
- 找到C++ Compiler -> Advanced(高级)选项卡
- 找到类似“Generate Underline Prefix”(生成下划线前缀)的选项,把它关掉
- 同时确认调用约定是
cdecl(Python要求入口函数用这个约定)
验证是否成功
编译完模块后,用Windows SDK里的dumpbin工具验证一下:
dumpbin /exports your_module.pyd
在输出的导出函数列表里,能看到PyInitialize_<你的模块名>没有下划线前缀,就说明没问题了,Python肯定能正常导入。
内容的提问来源于stack exchange,提问作者Totte Karlsson
相关产品推荐
相关产品推荐

