
用 SWIG 生成 C++ 多语言接口,核心是写好接口文件(.i),让 SWIG 解析 C++ 头文件并生成目标语言的胶水代码。整个过程不依赖 C++11 以上特性,兼容主流编译器和 Python/Java/Go/Node.js 等语言,关键是把类型映射、内存管理、异常转换这些细节理清楚。
一、准备 C++ 代码与 SWIG 接口文件
先确保你的 C++ 类或函数有清晰的头文件(如 math_utils.h):
// math_utils.h double add(double a, double b); int factorial(int n);
然后写 SWIG 接口文件 math_utils.i:
%module math_utils
%{
#include "math_utils.h"
%}
%include "math_utils.h"
注意:%{ %} 块里的内容会原样插入生成的包装代码中;%include 让 SWIG 解析头文件——它不预处理宏,所以避免在头文件里用未定义宏或模板声明。
立即学习“C++免费学习笔记(深入)”;
二、生成 Python 绑定(最常用)
命令行执行(以 Python 3.9 为例):
swig -c++ -python math_utils.i g++ -fPIC -shared math_utils_wrap.cxx math_utils.cpp -I/usr/include/python3.9 -lpython3.9 -o _math_utils.so
关键点:
- -c++ 表示输入是 C++ 代码
- 生成的 math_utils.py 是纯 Python 模块,_math_utils.so 是动态库,必须同目录
- 路径和 Python 版本要严格匹配,可用 python3-config --includes 和 --ldflags 获取准确参数
三、支持 Java / Node.js / Go(简配方案)
SWIG 对不同语言的支持程度不同,但基础流程一致:
- Java:加 -java 参数,生成 .java + .cxx,用 javac 编译 Java,g++ 编译动态库,再用 System.loadLibrary 加载
- Node.js:用 -node,生成 .js + .cxx,需配合 node-gyp 构建,注意 v8 API 版本兼容性
- Go:SWIG 官方支持有限,推荐用 -go 生成 .go + .h + .c,再通过 cgo 调用,C++ 类需封装为 C 风格接口(extern "C")
所有语言都默认不支持 STL 容器、智能指针、重载函数——需要手动添加 typemaps 或用 SWIG 的 %template、%shared_ptr 等指令扩展。
四、处理常见问题
实际绑定时容易卡在这几个地方:
- C++ 异常没转成目标语言异常:在 .i 文件开头加 %exception 块,捕获 std::exception 并转成 Python Exception 或 Java RuntimeException
- std::string / std::vector 无法自动识别:包含 SWIG 内置库,例如 %include "std_string.i"、%include "std_vector.i"
- 类成员函数调用崩溃:检查是否忘了 %include "std_shared_ptr.i",或对象生命周期没管理好(尤其返回裸指针时)
- Python 导入报 undefined symbol:确认 g++ 编译时链接了所有依赖库(比如 -lstdc++),且没有遗漏 -fPIC











