SWIG实现Python调用C++
在实际项目开发中,我们经常有跨语言交互的需求,比如使用Python/Lua脚本调用引擎代码。常用的方案有很多,我们来介绍SWIG
|
语言 |
特点 |
C++/CLI |
C++和C# |
微软为.NET平台高度定制的拓展,允许C++调用托管代码 |
SWIG |
多语言 |
跨平台多语言,需要写.i 文件,有一定侵入性 |
Boost |
Python和C++ |
|
JNI |
Java和C++ |
|
SWIG
简介
SWIG(Simplified Wrapper and Interface Generato)是一种包装器,通过配置.i
文件,自动生成Wrapper文件,以实现其他语言调用C++代码
Interface file
.i
文件格式如下
%module example
%{ #include "example.h" #include "example_controller.h" extern int fact(int); %}
%include <windows.i>
%array_class(bool, BoolArray);
%template(StringVector) std::vector<std::string>;
%include "example.h" %include "example_controller.h"
|
环境安装
我的环境是Mac M1,安装了brew和python3
- 安装swig
- 检测是否安装成功
样例代码
实现了在python中调用C++定义的add
函数
- C++代码
#include "example.h"
int add(int x, int y){ return x+y; }
|
- SWIG代码
%module example
%{ #include "example.h" %}
%include "example.h"
|
- 执行命令,我们会生成一个
.py
文件和一个.cxx
文件
swig -c++ -python example.i
|
- 为了方便使用,我们将生成的
.py
文件构建为.so
文件,创建一个setup.py文件,使用distutils进行编译
from distutils.core import setup, Extension example_module = Extension('_example', sources=['example_wrap.cxx', 'example.cpp'], ) setup (name = 'example', version = '0.1', author = "SWIG Docs", description = """Simple swig example from docs""", ext_modules = [example_module], py_modules = ["example"], )
|
执行命令,即会生成一些文件,其中包含一个.so
文件
python3 setup.py build_ext --inplace
|
- 将
.so
文件放入环境变量中(不推荐),或者放在python脚本同一个目录中(推荐),即可被调用
import example
result = example.add(3, 4) print("3 + 4 =", result)
|
C++包装
函数
#include "example.h" int add(int x, int y){ return x+y; }
|
%module example %{ #include "example.h" %} %include "example.h"
|
import example
result = example.add(3, 4) print("3 + 4 =", result)
|
常量
%module example %{ #include "example.h" %}
#define PI 3.14159265358979323846 %constant int Foo = 42; %constant const char *path = "/usr/local/include";
%include "example.h"
|
import example print(example.PI) print(example.path)
|
结构体
struct Point { double x,y; };
|
import example
p = example.Point() p.x = 1 p.y = 2
|
类
class Shape { private: double size; public: void setSize(double s) { size = s;} double getSize() { return size; } };
|
import example
s = example.Shape() s.setSize(0.5) print(s.getSize())
|
资料
SWIG 4.1 Doc