抱歉,您的浏览器无法访问本站
本页面需要浏览器支持(启用)JavaScript
了解详情 >

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文件格式如下

// 1. 模块名
%module example

// 2. 头文件和声明
%{
#include "example.h"
#include "example_controller.h"
extern int fact(int);
%}
// 引用其他.i文件
%include <windows.i>

// 3. swig特性

// 4. 代码拓展
// 将C++中的bool数组封装为BoolArray类
%array_class(bool, BoolArray);
// 将C++中的std::vector<std::string>封装为StringVector类,所有vector向量都应该像这样封装
%template(StringVector) std::vector<std::string>;

// 5. 要包装的内容,可以用头文件全部包装
// 特别注意,.h文件要按依赖顺序从上到下排布!
%include "example.h"
%include "example_controller.h"

环境安装

我的环境是Mac M1,安装了brew和python3

  1. 安装swig
brew install swig
  1. 检测是否安装成功
swig -version

样例代码

实现了在python中调用C++定义的add函数

  1. C++代码
// example.h
int add(int x, int y);
// example.cpp
#include "example.h"

int add(int x, int y){
return x+y;
}
  1. SWIG代码
// example.i
%module example

%{
#include "example.h"
%}

%include "example.h"
  1. 执行命令,我们会生成一个.py文件和一个.cxx文件
swig -c++ -python example.i
  1. 为了方便使用,我们将生成的.py文件构建为.so文件,创建一个setup.py文件,使用distutils进行编译
# setup.py
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
  1. .so文件放入环境变量中(不推荐),或者放在python脚本同一个目录中(推荐),即可被调用
# example_test.py
import example

# 调用C++函数
result = example.add(3, 4)
print("3 + 4 =", result)

C++包装

函数

// example.h
int add(int x, int y);
// example.cpp
#include "example.h"
int add(int x, int y){
return x+y;
}
// example.i
%module example
%{
#include "example.h"
%}
%include "example.h"
# example_test.py
import example
# 调用C++函数
result = example.add(3, 4)
print("3 + 4 =", result)

常量

// example.i
%module example
%{
#include "example.h"
%}

#define PI 3.14159265358979323846
%constant int Foo = 42;
%constant const char *path = "/usr/local/include";

%include "example.h"
# example_test.py
import example
print(example.PI) # 3.141592653589793
print(example.path) # /usr/local/include

结构体

// example.h
struct Point
{
double x,y;
};
# example_test.py
import example

p = example.Point()
p.x = 1
p.y = 2

// example.h
class Shape
{
private:
double size;
public:
void setSize(double s) { size = s;}
double getSize() { return size; }
};
# example_test.py
import example

s = example.Shape()
s.setSize(0.5)
print(s.getSize())

资料

SWIG 4.1 Doc

评论