作者博客:bot7.cc
SWIG可用来将C/C++语言的程序代码可进行包装,使其可以被其他高级语言(Python, go等)调用。SWIG功能非常强大,但是也正是因为其强大的功能,要想完全搞明白其用法其实并不简单。不过在实际应用中,通常只是相对简单的需求(例如用C/C++实现部分计算量较大的函数供其他语言调用),这种情况下其实上手还是很容易的。
本文将展示如何用SWIG将一个C++的类转化为Python扩展,以及如何在Python中导入和调用。
SWIG官方文档:http://www.swig.org/Doc4.0/Sections.html#Sections
安装SWIG
SWIG的安装方式有很多,可随意选择自己喜欢的方式进行安装。
直接安装
Windows
可直接在官网下载可执行文件。下载地址:swigwin-4.0.1
Linux
可用相应的包管理器直接安装。
Ubuntu/Debian: apt install swig
Mac OS
使用brew安装: brew install swig
使用pip安装
pip install swig
编译安装
下载源码
SWIG的源码可以在其官网下载:http://www.swig.org/download.html.
下载压缩包并将其解压。
运行配置文件
打开终端,进入源码目录并运行配置文件:
python configure.py
编译安装
make
make install
转化一个简单的C++类供Python调用
C++的代码通常有xxx.h
和xxx.cpp
一组文件组成,如果要使用SWIG进行转化,则需要针对你的头文件编写相应的xxx.i
文件。xxx.i
文件是告诉SWIG应该如何对代码进行包装,对于一些复杂的需求,也可以在xxx.i
文件中进行数据结构的转化(本文不涉及)。
假设我们有一个C++的类:PyCpp
pycpp.h
class PyCpp{
public:
PyCpp();
void sayHello();
};
pycpp.cpp
#include "pycpp.h"
#include <iostream>
using namespace std;
PyCpp::PyCpp(){
}
void PyCpp::sayHello(){
cout << "Hello Python, I am C++." << endl;
}
针对PyCpp
类编写pycpp.i
文件:
%module pycpp
%{
#include "pycpp.h"
%}
%inculde "pycpp.h"
使用SWIG生成转化文件
swig -c++ -python pycpp.i
调用SWIG后会生成pycpp_warp.cxx
和pycpp.py
文件,其中pycpp_warp.cxx
是转化后的C++文件,pycpp.py
是Python调用的接口文件。
编译链接
此时可以将pycpp.h
,pycpp.cpp
,pycpp_warp.cxx
三个文件编译链接为动态链接库,并重命名为_pycpp
。
linux下可用gcc编译:
gcc -fPIC -I/usr/include/python2.5/ -lstdc\+\+ -shared -o _pycpp.so pycpp_wrap.cxx pycpp.cpp
本人不太推荐此方法,更好一点的方法是使用distutils进行编译,编写setup.py文件:
from distutils.core import setup, Extension
pycpp_module = Extension('_pycpp',
sources=['pycpp.cpp', 'pycpp_wrap.cxx',],
)
setup (name = 'pycpp',
version = '0.1',
author = "NZACH",
description = """Simple swig C\+\+/Python example.""",
ext_modules = [pycpp_module],
py_modules = ["pycpp"],
)
终端进行编译打包:
python setup.py build_ext --inplace
在Python中调用
>>> import pycpp
>>> pycpp.PyCpp().sayHello()
Hello Python, I am C++.