一. SWIG 是Simple Wrapper and Interface Generator的縮寫,是一個幫助使用C或者C++編寫的軟件建立其餘編語言的API的工具。例如,我想要爲一個C++編寫的程序建立.NET API,通常狀況下我必須使用託管C++(Managed C++)去編寫大量的代碼才能生成它的.NET API。有了SWIG,這個機械的工做將變得很是簡單。你只需要使用一個接口文件告訴SWIG要爲那些類建立.NET API,SWIG就會自動幫你生成它的.NET API。java
當 然,SWIG不單單支持建立.NET API。最新版本的SWIG支持經常使用腳本語言Perl、PHP、Python、Tcl、Ruby和非腳本語言C#, Common Lisp (CLISP, Allegro CL, CFFI, UFFI), Java, Modula-3, OCAML以及R,甚至是編譯器或者彙編的計劃應用(Guile, MzScheme, Chicken)。也就是說能夠用Swig將C++接口封裝爲java等語言能夠調用的形式。python
二. 環境搭建c++
1. 下載swigwin,在E:/lib目錄下解壓,即把swig安裝到E:/lib/swig目錄中。windows
2. 新建一個Win32 Console Application,注意在Application Settings中選擇DLL以及空項目。完成後將工程的配置改爲releaseapi
3. 工具 —> 選項 —> 項目和解決方案 —> VC++目錄 —> 添加E:/lib/swigwin。即把swig添加到VC的可執行目錄。oracle
----------------若封裝成Python可用的API,執行以下步驟----------------------------app
4. 下載python2.5,安裝到D:/Program Files目錄,並在環境變量PATH中加入D:/Program Files/python2.5。工具
5. 把D:/Program Files/python2.5/include加入VC的Include路徑,將D:/Program Files/python2.5/libs加入VC的Library路徑。ui
-----------------若封裝成Java可用的API,執行以下步驟--------------------------------編碼
6. 下載JDK,安裝到D:/Program Files目錄,並在環境變量PATH中加入D:/Program Files/Java/jdk1.6.0_10/bin(若是以前安裝過Oracle,要將D:/Program Files/Java/jdk1.6.0_10/bin放在Oracle/jre/1.3.1/bin前面,不然在編譯的時候默認會選擇oracle的 jdk)
7. 把D:/Program Files/Java/jdk1.6.0_10/include/win32 和 D:/Program Files/Java/jdk1.6.0_10/include 加入到加入VC的Include路徑。
三. 接口文件
要在C/C++工程中建立***.i 的接口文件,告訴SWIG要爲那些類的那些方法建立API。
接口文件註解:
1. 模塊名由指定的%module來給出(或者用-module命令行選項).這段指示性文字必須寫在文件的頭部而且在使用時將這個模塊名做爲擴展模塊對象來 使用(此外,這個模塊名常常在目標語言中被定義成一個命名空間來使用)。若是模塊名在命令行已經被給出了,系統將不考慮由%module標示的模塊名了。
對於python:module的名字指定了生成文件xxx.py的xxx名字,
對於java:module的名字指定了生成文件xxx.java的xxx名字
2. 全部在%{...%}塊內的東西將被簡單做爲結果逐字拷貝到SWIG建立的wrapper(包裝)文件中。這部分大部分被用來包括頭文件和生成 wrapper代碼須要的其它聲明。這裏很重要的強調一點由於你在一個SWIG的輸入文件中包含了一個聲明,這個聲明並不自動顯示在生成的wrapper 代碼中,所以你須要確信你確實把正確的頭文件在%{ ... %}部分中。這裏應該指出SWIG不解析和解釋附在%{ ... %}部分的文字。SWIG的%{...%}內的語法和語義很相似於輸入文件中的聲明部分 。
3. 若是打算爲類中全部方法建立API,那麼有一個很是簡單的辦法,在接口文件的類聲明部分使用%include標記。SWIG將對%include所指定的文件進行語法分析,類中全部公有方法(Public Method)都將在API中暴露。
/* SwigTest.i */
%module SwigTest
%{
#include "SwigTest.h"
%}
%include 「SwigTest.h」 //不要和#用混
-------------------------- swig庫模塊訪問部分標準C++庫包括STL的方法-------------------
SWIG對於一些語言模塊的支持使較全面的可是對不多用到的庫則支持的不多。
下面就是表示了C++類和支持的C++庫 以及SWIG接口文件的對應表
C++ class C++ Library file SWIG Interface library file
std::deque deque std_deque.i
std::list list std_list.i
std::map map std_map.i
std::pair utility std_pair.i
std::set set std_set.i
std::string string std_string.i
std::vector vector std_vector.i
所以,當C / C++代碼中用到這些庫時,可將swig對應的接口文件添加到本身的接口文
件中。如:%include "std_string.i",
庫文件徹底識別C++的命名空間。若是你輸出std::string 或 將它重命名爲另外一種類型。請確認你將此重命名聲明包含到了你的接口文件中。例如:
%module example
%include "std_string.i"
using namespace std;
typedef std::string String;
...
void foo(string s, const String &t); // std_string typemaps still applied
當 封裝java調用的api且傳遞的參數中含有中文時,因爲c++中的String是使用單字節編碼,而java中String是使用Unicode編碼, 因此爲了傳遞時不出現亂碼,能夠包含%include "std_wstring.i",由於wstring使用的是wchar_t類型,這是寬字符,用於知足非ASCII字符的要求,例如Unicode編 碼。
當封裝python調用的api且傳遞的參數中含有中文時,就不用考慮這個編碼問題,能夠直接使用c++中的String。
四. 編譯模塊
1.寫接口執行命令
有 了接口文件之後要對接口文件進行編譯,右鍵點擊接口文件,修改它的屬性,使用自定義編譯工具(Custom Build Tool),命令行(Command Line)內容爲swig.exe -c++ -python SwigTest.i ,輸出(Outputs)爲$(InputName)_wrapper.cpp;
echo JAVA_INCLUDE: %JAVA_INCLUDE%
echo JAVA_BIN: %JAVA_BIN%
echo on
swig.exe -c++ -python SwigTest.i
命令行參數說明:
① 爲了編譯java 或python模塊,必須包含它們的include和bin目錄,能夠在PATH中設置JAVA_INCLUDE、JAVA_BIN、 PYTHON_INCLUDE、PYTHON_BIN等,其中include能夠在工程屬性中設置,若是工程屬性中已經設置好,此處不用再包含頭兩句。
②「 swig.exe 」表示調用你安裝的swig的可執行文件,以前已經將其目錄加入到VC的可執行目錄中,因此此處就能夠不用再寫路徑,不然要找到swig路徑才行。
③ 「-c++」 表示要封裝C++代碼(不寫默認是封裝C代碼),
④「-python」表示要封裝成Python接口(Swig還能夠封裝成Java、Ruby等接口),
⑤ 「$(InputName)_wrapper.cpp」表示指定要生成的C++代碼文件的名字。
swig的命令還有其餘的一些,目前用到的如 –package命令,用法能夠爲:
swig -java -package com.swig -outdir com/swig example.i
在生成java的api時,這個命令使生成的java文件包含在某個包中。
2.編譯(右鍵點擊接口文件—>編譯)
對於生成python可用的API:執行上述命令會生成兩個新的文件,一個是SwigTest.py,一個是SwigTest_wrapper.cpp。
對於生成java可用的API:執行上述命令會生成Java類文件:SwigTestJNI.java,SwigTest.java
和c文件SwigTest_wrapper.cpp。
3.將xxx_wrapper.cpp加入到工程
4.修改工程屬性:
-----------------------封裝java可用的api---------------------
LinkeràGeneralàOutput File改爲SwigTest.dll
Build EventsàPost-Build EventàCommand Line改爲:
echo on
"%JAVA_BIN%/javac" *.java
這個命令做用是編譯完後調用javac將當前編譯路徑下的全部.java文件編譯成.class二進制文件。
-----------------------封裝python可用的api---------------------
LinkeràGeneralàOutput File改爲_SwigTest.pyd(注意必定要有下劃線)
還有一些配置在VC2005裏是默認的,但在VC2003裏不是的,請引發注意,包括
① C/C++àCode GenerationàRuntime Library要選擇Multi-threaded DLL (/MD)
② C/C++àLanguageàTreat wchar_t as Built-in Type要選擇yes(若是轉換不涉及wchar等,則無需處理這一項)
③ C/C++àLanguageàEnable Run-Time Type Info要選擇yes
5.生成工程
五.利用生成的api就能夠在對應的腳本語言(java、python等)中使用啦。
windows環境2.0.7版:http://prdownloads.sourceforge.net/swig/swigwin-2.0.7.zip