SWIG實戰 - C/C++轉化Python擴展 - 簡單例子
SWIG簡介
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文件:
%{
#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++.
