Android突破八.使用SWIG將C/C++庫移植到其餘語言中

使用SWIG將C/C++庫移植到其餘語言中
javascript

1、使用SWIG將C轉換成Java
html

1.SWIG簡介
java

SWIG是一個將C和C++語言程序綁定到其餘語言的工具,可讓不少高層次的程序設計語言如腳本語言很方便地調用底層程序。SWIG支持不少的語言如Perl, PHP, Python, Tcl, Ruby, Java, C#, Octave和R等,這些語言在不一樣程度上支持本地接口調用。利用SWIG,只需寫一些接口文件就能夠生成一些用相應語言的本地接口庫封裝的代碼。利用C和C++編譯器編譯成動態庫文件後,就能夠直接用高層次的語言調用了。SWIG在不少的跨平臺的項目中都獲得了普遍的應用,例如Subversion, PyOgre, PyOpenGL, wxPython等。
2.SWIG的下載與安裝
在Ubuntu系統的軟件源上有SWIG軟件包,能夠直接經過如下命令安裝。
sudo apt-get install swig
在Windows系統或者其餘的Linux版本上,能夠下載源代碼包,下載地址:http://prdownloads.sourceforge.net/swig/swig-2.0.9.tar.gz。
在Linux系統下,解壓縮後,運行
./configure
make

編譯完成後就可使用。
在Windows系統下,建議安裝MinGW或者Cygwin,使用gcc編譯器編譯。
3.準備源文件和接口文件
在運行SWIG以前,首先要準備好C/C++程序的源文件,並編寫接口文件linux

這裏採用一個簡單的例子,要封裝的是一個叫作Example的模塊。
swig -java Example.i
功能:咱們要導出Example.c文件中全部變量和函數中安全

(1)C程序源文件Example.c
jvm

/* Example.c */
include <stdio.h>
int integer = 100;
int add(int a, int b)
{
        return a + b;
}
char* getString()
{
        return "Some string";
}
void printLine(const char* str)
{
        printf("%s\n", str);
}

(2)建立接口文件Example.i,輸入如下內容:
%module Example
%{
extern int integer;
extern int add(int a, int b);
extern char* getString();
extern void printLine(const char* str);
%}
extern int integer;
extern int add(int a, int b);
extern char* getString();
extern void printLine(const char* str);
 

Example.i中%module後面是庫的名稱,%{和%}中的內容是要加入到生成文件中的內容,一般是函數和變量的定義和要包含的頭文件,做用是讓生成的源文件愛女可以經過編譯。以後的內容是正常的C函數和變量的定義,與正常C語言的語法相同。
4.使用SWIG生成Java類文件
(1)默認將生成Example_wrap.c, Example.java, ExampleJNI.java三個文件
swig -java Example.i
(2)編譯共享庫文件。
gcc -c -fPIC Example.c Example_wrap.c -I/usr/lib/jvm/java-7-openjdk-amd64/include/
gcc -shared -o libExample.so Example.o Example_wrap.o
注意編譯時要包含Java本地接口頭文件jni.h所在的目錄,這個文件的位置在不一樣系統中不一樣,編譯時須要加入。
(3)測試
如今就已經可使用SWIG生成的類文件Example.java和相應的JNI文件ExampleJNI.java來調用庫函數了。新建一個文件Main.java來測試一下。
函數

public class Main{
        public static void main(String args[]){
                System.loadLibrary("Example");
                System.out.println("getInteger(): " + Example.getInteger());
                Example.setInteger(100);
                System.out.println(Example.getInteger());
                System.out.println("1 + 2 = " + Example.add(1, 2));
                System.out.println("getString(): " + Example.getString());
                Example.printLine("printString()");
        }
}
編譯運行:
javac Main.java
java Main
輸出結果以下所示:
getInteger(): 100
100
1 + 2 = 3
getString(): Some string
printString()
總結:
SWIG的功能很強大,能夠支持不少語言。這裏只測試了 Java語言的封裝 ,對於其餘語言,方法也比較相似,只是在編譯的時候須要包含相應的本地庫頭文件,如Python中的Python.h,Java中的jni.h。另外,這裏演示的只是最簡單的接口文件的編寫,實際上,接口文件能夠有更多的選項,這些在SWIG的文檔中有更詳細的說明。C語言的封裝相對比較簡單,對於C++這樣的面向對象的語言,接口文件的編寫略微複雜,可是也比較容易掌握。固然,在調用這些本地接口的時候還有一個問題,就是安全性。在設計接口的時候也要充分意識到安全性問題,防止指針錯誤和內存泄漏等。雖然SWIG已經可以很好地處理指針,但有的時候還須要本身去實現指針的封裝。

2、使用SWIG將C轉換成tcl工具

1.下面是測試用的whichday.c和whichday.i文件 /*whichday.c文件, 功能是計算一個日期是這一年的第幾天*/ 
#include <stdio.h> 
void whichday(int year,int month,int day) 
{
     int sum,leap; 
     switch(month)/*先計算某月之前月份的總天數*/ 
     { 
     case 1:sum=0;break;
     case 2:sum=31;break; 
     case 3:sum=59;break; 
     case 4:sum=90;break; 
     case 5:sum=120;break; 
     case 6:sum=151;break; 
     case 7:sum=181;break; 
     case 8:sum=212;break; 
     case 9:sum=243;break; 
     case 10:sum=273;break; 
     case 11:sum=304;break; 
     case 12:sum=334;break; 
     default:printf("data error");break; 
 } 
      sum=sum+day; /*再加上某天的天數*/ 
      if(year%400==0||(year%4==0&&year%100!=0))/*判斷是否是閏年*/ 
             leap=1; 
      else 
             leap=0; 
      if(leap==1&&month>2)/*若是是閏年且月份大於2,總天數應該加一天*/ 
             sum++; 
             printf("It is the %dth day.",sum); 
 } 
 /* whichday.i*/ 
%module whichday 
%{ 
     extern void whichday(int a,int b,int c);
 %} extern void whichday(int a,int b,int c);      
2.各類平臺使用

Windows下 VC6.0  swig-1.3.34  tcl8.5測試

一、編寫whichday.c whichday.i 文件url

二、用命令:swig –tcl whichday.i 產生whichday_wrap.c 文件

三、1)在VC6.0下新建一個 的空DLL工程。

2)對VC6.0進行設置。工程---->設置-à鏈接,在對象/庫模板中添加tcl85.lib(不一樣版本的tcl會不同,要作相應改    變)。

3)接着,工具-à選項-à目錄,在目錄選項的include file中添加tcl腳本的include 文件的位置,一樣在library中添加lib文件,以後點肯定。        

4)在工程下分別新建名爲whichday.c和 whichday_wrap.c 的sourse file 文件,

           將步驟1,步驟2產生的對應文件複製到這兩個文件中。

5)最後執行 編譯 à創建。         這樣就在工程目錄的dubug目錄下產生了一個whichday.dll 文件。

四、在命令行下,輸入命令,應用生成的whichday.dll 文件。

         Tclsh

         Load ./whichday.dll

         Whichday 2012 3 28

各類平臺下用Siwg將C轉換成Tcl - huger - Huger的博客

Linux (Ubuntu10.10)下用swig tcl

 

一、  安裝sudo apt-get install swig

二、  編寫whichday.c whichday.i(接口)文件

在終端下面運行下面幾條命令(要在上面兩個文件所在目錄下面)

三、  運行swig -tcl whichday.i,生成whichday_wrap.c

四、  運行gcc -c whichday.c whichday_wrap.c -I/usr/include/tcl8.4

(由於tcl.h是位於/usr/include/tcl8.4目錄下面,要根據本身的狀況更改)

五、  運行gcc -shared whichday.o whichday_wrap.o -o whichday.so  生成whichday.so 

六、  運行Tclsh,調用whichday.so
               load ./ whichday.so 
               whichday 2012 3 28

        運行結果以下圖:

 各類平臺下用Siwg將C轉換成Tcl - huger - Huger的博客

 

Cygwin 下swig  tcl

一、編寫whichday.c whichday.i 文件
       二、命令swig -tcl whichday.i,  生成whichday_wrap.c文件
       三、命令gcc -c whichday.c whichday_wrap.c
       四、命令gcc -shared whichday.o whichday _wrap.o -L/lib /lib/libtcl.a -o whichday.so

    (注意:上面 -L/lib 與 /lib/libtcl.a 之間有空格)
       五、Tclsh
             load ./ whichday.so

      whichday

       各類平臺下用Siwg將C轉換成Tcl - huger - Huger的博客

         (上圖中出現的錯誤一直沒有找到緣由)

http://wenku.baidu.com/link?url=X5IiK5b174dLg5wIvxiD50D8uH6Wk5N0XK_5nefREwzn7-cvJsKpwfpGy-IpPz6IVSgg_SapQ-KEKLvXfjJzI90iYTnCFAYZhSxytIMPXte
http://www.linuxidc.com/Linux/2012-07/64574p2.htm http://www.linuxidc.com/Linux/2013-01/78270.htm http://www.swig.org/Doc2.0/Android.html