You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

能否使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:51:19