SWIG 是一个帮助使用C或C++编写的软件能与其他各种高级语言进行嵌入链接的工具
- SWIG支持多种语言:Python,Java,PHP,Perl,Tcl和Ruby
- 相比较使用 python 自带扩展方法和Cython方法,SWIG不要求修改C/C++代码,根据C/C++的声明,对其进行包裹使得其他语言可以访问
使用方法
- 安装 SWIG
# for linux
sudo apt-get install swig
# for windows
直接下载编译后的文件,设置环境变量即可
- 编写C/C++源代码
- 编写接口文件 .i
- 封装代码
swig -python -c++ file.i
会生成 file.py 和 file_wrap.cxx
- 生成动态链接库
编写 setup.py 文件
from distutils.core import setup, Extension
pht_module = Extension('_modulename',
sources=['file_wrap.cxx',
'file.cpp'],
)
setup(name = 'modulename',
version = '0.1',
author = 'SWIG Docs',
description = 'Simple swig pht from docs',
ext_modules = [pht_module],
py_modules = ['modulename'],
)
python setup.py build_ext
生成 _modulename.so
语法细节
假定一个类 do_something,包含一个方法 printContext(vector& context),接受一个 vector 并打印出来
1)C++源文件
// file: dosomething.h
#ifndef DO_SOMETHING_H
#define DO_SOMETHING_H
#include "string"
#include "vector"
using namespace std;
class do_something
{
public:
do_something();
~do_something();
public:
void printContext(vector<string>& context);
};
#endif
// file: dosomething.cpp
#include "dosomething.h"
#include "iostream"
do_something::do_something(){
cout << "i have constructed!" <<endl;
}
do_something::~do_something(){
cout << "i have destructed!" <<endl;
}
void do_something::printContext(vector<string>& context){
for(int i=0; i<context.size(); i++)
cout << context[i] << endl;
}
2)接口文件 dosomething.i
%module dosomething
%{
#include "dosomething.h"
%}
%include "std_string.i"
%include "std_vector.i"
%include "dosomething.h"
%template(StringVector) vector<string>;
- module 的名字指定了生成 xxx.py 的名字
- %{…%} 以内的东西将逐字拷贝到SWIG创建的 wrapper 文件中
- %include “dosomething.h” 将会对头文件中所有公有方法创建API
- %include “std_string.i” 和 %include “std_vector.i”是 SWIG提供的 C++ 对应的库文件
C++ class | SWIG Interface library file |
---|---|
std::deque | std_deque.i |
std::list | std_list.i |
std::map | std_map.i |
std::pair | std_pair.i |
std::set | std_set.i |
std::string | std_string.i |
std::vector | std_vector.i |
%template(StringVector) vector<string>;
将会额外生成一个类 StringVector,用以描述vector<string>
对象3)setup.py 文件
from distutils.core import setup, Extension
pht_module = Extension('_dosomething',
sources=['dosomething_wrap.cxx',
'dosomething.cpp'],
)
setup(name = 'dosomething',
version = '0.1',
author = 'SWIG Docs',
description = 'Simple swig pht from docs',
ext_modules = [pht_module],
py_modules = ['dosomething'],
)
使用库
图1. 用 dir 看模块内所有类成员
可以看到,经过包装后,类方法变成 classname_function 的格式(do_something_printContext)
此外所有方法均增加一个参数,用以输入类对象
构造和析构函数被封装为 new_classname 和 delete_classname 的形式