【Python】C++ & Python 混合編程(4)-- Python 調用 C++(SWIG)

SWIG 是一個幫助使用C或C++編寫的軟件能與其他各種高級語言進行嵌入鏈接的工具

  • SWIG支持多種語言:Python,Java,PHP,Perl,Tcl和Ruby
  • 相比較使用 python 自帶擴展方法Cython方法,SWIG不要求修改C/C++代碼,根據C/C++的聲明,對其進行包裹使得其他語言可以訪問

使用方法

參考文章《使用SWIG實現Python調用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 的形式


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章