使用SWIG封装C++类遇Windows导出宏问题(VS2018+Python3.7+SWIG3.0.12)
使用SWIG 3.0.12封装C++类(VS2018 + Python3.7)
我来帮你梳理一下用SWIG 3.0.12在VS2018环境下为Python3.7封装这个C++类的完整步骤,结合你给出的代码细节:
1. 补全导出宏定义
你的atCoreExporter.h代码截断了,我补全Windows平台下标准的DLL导出/导入宏定义,这样SWIG才能正确识别类的导出属性:
#ifndef atCoreExporterH #define atCoreExporterH // Windows平台DLL导出/导入宏配置 #ifdef _WIN32 #ifdef AT_CORE_EXPORTS #define AT_CORE __declspec(dllexport) #else #define AT_CORE __declspec(dllimport) #endif #else // 非Windows平台无需特殊标记 #define AT_CORE #endif #endif
2. 核心类头文件(atATObject.h)
这部分保持你原有的代码即可:
#ifndef atATObjectH #define atATObjectH #include "core/atCoreExporter.h" #include <string> //-------------------------------------------------------------------------- using std::string; class AT_CORE ATObject { public: ATObject(); virtual ~ATObject(); virtual const string getTypeName() const; }; #endif
3. 编写SWIG接口文件(ATObject.i)
SWIG需要一个接口文件来描述要导出的内容,创建ATObject.i文件:
%module ATObject // 告诉SWIG要包含的头文件(内部编译用) %{ #include "atATObject.h" %} // 引入SWIG对std::string的支持库,避免字符串类型转换问题 %include <std_string.i> // 导出ATObject类的所有公共接口 %include "atATObject.h" // 如果需要在Python中重写C++的虚函数,添加下面这行 // %feature("director") ATObject;
4. VS2018项目配置步骤
4.1 创建项目
- 新建一个Win32控制台应用程序,选择“DLL”类型,勾选“空项目”。
- 将你的
atATObject.h、atCoreExporter.h、对应的cpp实现文件(比如atATObject.cpp)和ATObject.i添加到项目中。
4.2 配置SWIG自定义生成工具
右键点击ATObject.i文件 → 属性:
- 常规 → 项类型:选择“自定义生成工具”,点击应用。
- 自定义生成工具 → 常规:
- 命令行:填写SWIG的执行命令,注意替换成你的SWIG路径:
解释:"C:\Path\To\SWIG\swig.exe" -c++ -python -outdir "$(SolutionDir)PythonBindings" "$(ProjectDir)ATObject.i"-c++指定处理C++代码,-python生成Python绑定,-outdir指定生成的.py文件输出目录。 - 输出:填写生成的文件路径:
$(SolutionDir)PythonBindings\ATObject.py;$(ProjectDir)ATObject_wrap.cxx
- 命令行:填写SWIG的执行命令,注意替换成你的SWIG路径:
- 点击确定保存配置,此时VS会自动生成
ATObject_wrap.cxx文件并加入项目。
4.3 项目编译配置
右键项目 → 属性:
- C/C++ → 常规:添加头文件包含目录(比如包含
core文件夹的路径,确保能找到atCoreExporter.h)。 - C/C++ → 预处理器:添加
AT_CORE_EXPORTS到预处理器定义(这样AT_CORE宏会被解析为__declspec(dllexport),确保类被导出为DLL符号)。 - 链接器 → 常规:设置输出目录为Python的
site-packages目录,或者后续手动复制生成的.pyd文件到Python能识别的路径。 - 链接器 → 输入:如果你的项目依赖其他库,添加对应的库文件。
5. 编译与测试
- 编译项目,会生成两个关键文件:
ATObject.py:Python调用的接口文件_ATObject.pyd:编译后的Python扩展库(本质是DLL)
- 在Python中测试:
import ATObject obj = ATObject.ATObject() print(obj.getTypeName())
常见注意事项
- 确保SWIG 3.0.12的路径加入系统环境变量,或者在命令行中写绝对路径。
- 如果你的
getTypeName()有具体实现,确保在cpp文件中正确返回字符串,比如:const string ATObject::getTypeName() const { return "ATObject"; } - 如果需要在Python中重写C的虚函数,记得在SWIG接口文件中添加
%feature("director") ATObject;,同时编译时要启用RTTI(C/C → 语言 → 启用运行时类型信息)。
内容的提问来源于stack exchange,提问作者Totte Karlsson
相关产品推荐
相关产品推荐

