在windows下使用SWIG的環境配置問題(將c/c++轉為java語言)
在Windows下安裝:
SWIG的安裝不同於一般的Windows安裝程序,它相對而言更加容易上手。主要的步驟如下:
1.從SWIG網站下載swigwin壓縮包然后解壓縮到一個目錄。這就是我們下載Windows平台下的版本的所有事情。
2.像Swig Windows 例子部分描述的設置環境變量來用Visual C++運行案例.
Java下環境變量的設置:
JAVA_INCLUDE : Set this to the directory containing jni.h
JAVA_BIN : Set this to the bin directory containing javac.exe
Example using JDK1.3:
JAVA_INCLUDE: d:\jdk1.3\include
JAVA_BIN: d:\jdk1.3\bin
在win2000系統的環境參數中添加兩個新的變量JAVA_INCLUDE和AVA_BIN,值分別為
d:\jdk1.3\include和d:\jdk1.3\bin。即對應的java的安裝目錄
//
SWIG對c/c++中對象和類型的支持?
ANSI C (標准C)
SWIG能夠打包封裝的標准C對象包括:
1.所有標准C數據類型
2.全局函數,全局變量,和常量
3.結構體和聯合體
4.指針
5.數組和多維數組
6.指針函數
7.可變長度的參數.
8.類型定義Typedef
9.枚舉Enums
ANSI C++ (標准C++)
SWIG提供對幾乎所有標准C++對象的封裝:
1.所有C++數據類型
2.參數
3.成員指針
4.類
5.繼承和多重繼承
6.重載函數和方法(使用動態接口)
7.重載操作
8.靜態成員
9.命名空間(包括使用聲明,別名,嵌套,等)
10.模板
11.成員模板
12.特殊模板和部分特殊應用
13.Smart指針
14.支持strings,STL vector等的庫
The only major C++ feature not currently supported by SWIG is the wrapping of nested classes--a problem we're working on. SWIG also does not allow C++ virtual methods to be implemented in certain target languages (a subtle feature that might be useful in projects that rely heavily on the use of callback functions).
C++ users who rely on advanced template programming techniques (e.g., template meta-programming) should also be aware that SWIG currently requires manual instantiation of all template classes. Therefore, if your application somehow involves the instantiation of 50000 template classes, your mileage might vary.
SWIG輸入數據格式:
在輸入上,SWIG需要包括C/C++聲明和特殊的SWIG指示的一個文件。大部分來說, 這是一個特殊的SWIG
接口文件通常是特指.i或.swg的文件格式。在特殊的情況下,SWIG能直接被用於原始的頭文件或源文件。
但是,這並不是最通常的典型使用案例而且會有幾種原因使你不會想這樣做(原因在后面會講述)。
最通常的SWIG接口文件格式如下:
%module mymodule
%{
#include "myheader.h"
%}
// Now list ANSI C/C++ declarations
int foo;
int bar(int x);
...
模塊名由指定的%module來給出(或者用-module命令行選項).這段指示性文字必須寫在文件的頭部並且
在使用時將這個模塊名作為擴展模塊對象來使用(此外,這個模塊名經常在目標語言中被定義成一個命
名空間來使用)。如果模塊名在命令行已經被給出了,系統將不考慮由%module標示的模塊名了。
所有在%{...%}塊內的東西將被簡單作為結果逐字拷貝到SWIG創建的wrapper(包裝)文件中。這部分大部分
被用來包括頭文件和生成wrapper代碼需要的其它聲明。這里很重要的強調一點因為你在一個SWIG的輸入
文件中包含了一個聲明,這個聲明並不自動顯示在生成的wrapper代碼中———因此你需要確信你確實
把正確的頭文件在%{ ... %}部分中。這里應該指出SWIG不解析和解釋附在%{ ... %}部分的文字。SWIG的
%{...%}內的語法和語義很類似於輸入文件中的聲明部分???
/
SWIG使用說明
1.編寫interface文件example.i
如果api有頭文件就更簡單了,下面的代碼定義一個example類
example.i文件
%module example
%{
#include "example.h"
%}
%include "example.h"
2. swig -java example.i
生成符合JNI語法(見上)的C文件: example_wrap.c
生成Java類文件:exampleJNI.java,example.java
swig -c++ -java example.i
同時生成example_wrap.c 文件
3.VC把example_wrap.c 和example.c 打包成dll.
4.在普通java程序里使用example.java
System.loadLibrary("example");
int g = new Example().add(42,105);
//
STL/C++庫的轉化
這一部分的庫模塊提供訪問部分標准C++庫包括STL的方法。使SWIG支持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
這個表應該說還沒有很完善。一些語言模塊支持上面的一個子集而另一些支持擴展的STL類.請仔細尋找
相關語言庫目錄下的庫文件。
1.std_string.i
這個std_string.i庫提供將C++ std::string對象轉化為目標描述性語言的方法。舉例:
(在example.i中)
%module example
%include "std_string.i"
std::string foo();
void bar(const std::string &x);
在目標語言中:
x = foo(); # Returns a string object
bar("Hello World"); # Pass string as std::string
人們碰到的一個最常見的問題是在 類/結構 中包含一個 std::string。這個問題可以通過定義一個typemap來解決。
例如:
%module example
%include "std_string.i"
%apply const std::string& {std::string* foo};
struct my_struct
{
std::string foo;
};
在目標語言中:
x = my_struct();
x.foo="Hello World"; # assign with string
print x.foo; # print as string
這個模塊只支持std::string 和 const std::string &兩種寫法。指針和 非常量參數將被無修改的保留下來
並作為SWIG的指針返回。
庫文件完全識別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
注:std_string庫轉換為Perl時在某些系統平台下出現不兼容性。我們正在查找原因。
-----------------------------------------------------------------------------------------------
2.std_vector.i
std_vector.i庫提供了對C++ STL中的vector類的支持。使用此庫通常包括使用%template 標識。你所需要做的
就是分清你要使用的vector中的數據類型。例如:
%module example
%include "std_vector.i"
namespace std {
%template(vectori) vector;
%template(vectord) vector;
};
/
SWIG 對C++類繼承的支持
SWIG支持單繼承,一般可以很好的將單繼承的類轉為java對象。對多繼承支持的程度不太好,需要人工參與.i文件的修改,詳細請查找資料。
/
SWIG封裝包不支持以下的C++語法:
1.重載方法和重載函數。SWIG封裝不知道如何解決同名沖突因此你必須給每一個同名重載方法一個替換的名稱,具體方法
是用%name如下所示:
void foo(int a);
%name(foo2) void foo(double a, double b);
2.重載操作???。並不完全支持。對此唯一的工作區是寫一個幫助函數。例如:
%inline %{
Vector *vector_add(Vector *a, Vector *b) {
... whatever ...
}
%}
3.命名空間。不完全支持。直到SWIG2.0發布以前將不會得到支持。
//
在VC++6.0的.dsp工程設置文件中配置SWIG調用
舉例說明:
1.首先在Project->Settings->Post-build step選項卡下
Post-build description文字框中輸入Java compile post-build step
在下面的commands中添加
echo on
"%JAVA_BIN%\javac" *.java
這兩句話的意思是編譯完后調用javac將當前編譯路徑下的所有.java文件編譯成.class二進制文件。
2.然后用寫字版打開.dsp文件
在文件的倒數第四行# Begin Source File后添加
SOURCE=.\example.i
#DEBUG版本情況下的設置
!IF "$(CFG)" == "example - Win32 Debug"
# Begin Custom Build 開始客戶方生成
InputPath=.\example.i
InputName=example
"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
echo In order to function correctly, please ensure the following environment variables are correctly set:
echo JAVA_INCLUDE: %JAVA_INCLUDE%
echo JAVA_BIN: %JAVA_BIN%
echo on
..\..\..\swig.exe -c++ -java $(InputPath)
# End Custom Build 結束客戶方生成
#RELEASE版本情況下的設置
!ELSEIF "$(CFG)" == "example - Win32 Release"
# Begin Custom Build 開始客戶方生成
#指定輸入路徑和輸入名稱
InputPath=.\example.i
InputName=example
#調用swig -c++ -java生成對應的java文件(.java)
"$(InputName)_wrap.cxx" : $(SOURCE) "$(INTDIR)" "$(OUTDIR)"
echo In order to function correctly, please ensure the following environment variables are correctly set:
echo JAVA_INCLUDE: %JAVA_INCLUDE%
echo JAVA_BIN: %JAVA_BIN%
echo on
..\..\..\swig.exe -c++ -java $(InputPath)
# End Custom Build 結束客戶方生成