SWIG封装C代码
? 注意到.i接口文件中定義的組件僅僅是為了SWIG來讓java可以訪問。他們并不會包含在產生的文件中,除非他們也被定義插入預處理定義中。
? ?全局變量:
? ? swig支持全局變量。SWIG產生getter和setter方法在模塊類中來提供獲得本地全局的變量。為了讓全局變量被Java獲得,增加它到接口文件。
? ??%module Unix
? ? . . .
? ? /* Global counter. */
? ?extern int value;
? ?. . .
? ?public static void setCounter(int value) {
? UnixJNI.counter_set(value);
? }
? public static int getCounter() {
? return UnixJNI.counter_get();
? ?}
?}
常量的定義:
常量被定義在接口文件,通過#define或者%constant預處理命令
? ? %module Unix
? ? . . .
? ?/* Constant using define directive. */
? ?#define MAX_WIDTH 640
? /* Constant using %constant directive. */
? %constant int MAX_HEIGHT = 320;
SWIG產生一個Java接口命名為<module>Contant,和常量被展示作為靜態常量變量在這個接口中:
??public interface UnixConstants {
? ? ? ? public final static int MAX_WIDTH = UnixJNI.MAX_WIDTH_get();
? ? ? ? public final static int MAX_HEIGHT = UnixJNI.MAX_HEIGHT_get();
? }
默認Swig產生運行時常量。通過JNI函數調用本地代碼來初始化這些常量。這可以被改變通過使用這%javaconst預處理在接口文件,如下:
??%module Unix
? . . .
?/* Constant using define directive. */
?%javaconst(1);
?#define MAX_WIDTH 640
?/* Constant using %constant directive. */
?%javaconst(0);
?%constant int MAX_HEIGHT = 320;
這個預處理指令命令SWIG來產生編譯時常量對于Max_WIDTH和一個運行時常量對于Max_Height.這個Java接口如下:
? ?package com.apress.swig;
? ?public interface UnixConstants {
? ?public final static int MAX_WIDTH = 640;
? ?public final static int MAX_HEIGHT = UnixJNI.MAX_HEIGHT_get();
? ?}
只讀變量:
? ?SWIG提供這個%immutable預處理指令來標記一個只讀變量,如下:
? ?%module Unix
? ?. . .
? /* Enable the read-only mode. */
? %immutable;
? /* Read-only variable. */
? extern int readOnly;
? /* Disable the read-only mode. */
? %mutable;
Setter Method Is Not Generated for the Read-only Variable
. . .
public static int getReadOnly() {
return UnixJNI.readOnly_get();
}
public static void setReadWrite(int value) {
UnixJNI.readWrite_set(value);
}
public static int getReadWrite() {
return UnixJNI.readWrite_get();
}
}
枚舉類型:
? SWIG能夠處理命名的和匿名的枚舉變量。產生枚舉變量有四種不同的方式:
匿名:
匿名枚舉被定義在接口文件,如下:
%module Unix
. . .
/* Anonymous enumeration. */
? enum { ONE = 1, TWO = 2, THREE, FOUR };
?Swig在產生靜態變量的<Module>Constants的Java接口對于每個enumeration,如下。想常量一樣也產生運行時枚舉常量。這個%javaconst預處理也能夠產生編譯時枚舉常量。
? ?package com.apress.swig;
? ?public interface UnixConstants {
? ? ? . . .
? ? ? public final static int ONE = UnixJNI.ONE_get();
? ? ? public final static int TWO = UnixJNI.TWO_get();
? ? ? public final static int THREE = UnixJNI.THREE_get();
? ? ? public final static int FOUR = UnixJNI.FOUR_get();
? ?}
類型安全:
?不像匿名的枚舉常量,他們在Java中作為類型安全的枚舉常量。
?%module Unix
?. . .
?/* Named enumeration. */
?enum Numbers { ONE = 1, TWO = 2, THREE, FOUR };
?SWIG定義了一個帶有枚舉的名字的單獨類和枚舉值被展示為一個不變的靜態的成員屬性,如下:
? ?package com.apress.swig;
? ?public final class Numbers {
? ?public final static Numbers ONE = new Numbers("ONE", UnixJNI.ONE_get());
? ?public final static Numbers TWO = new Numbers("TWO", UnixJNI.TWO_get());
? ?public final static Numbers THREE = new Numbers("THREE");
? ?public final static Numbers FOUR = new Numbers("FOUR");
? ?. . .
? /* Helper methods. */
? . . .
}
enumtypeunsafe.swg的擴展名:
? %include "enumtypeunsafe.swg"
? /* Named enumeration. */
? enum Numbers { ONE = 1, TWO = 2, THREE, FOUR };
產生的對于枚舉類型的Java類如下。這種類型的枚舉能夠用作switch語句,因為他們是基于常量的。
package com.apress.swig;
public final class Numbers {
public final static int ONE = UnixJNI.ONE_get();
public final static int TWO = UnixJNI.TWO_get();
public final static int THREE = UnixJNI.THREE_get();
public final static int FOUR = UnixJNI.FOUR_get();
}
Java的枚舉類型:
對于Java的枚舉類型,也能夠展示個Java。這種類型的枚舉也是類型檢查的,和他們能夠用在switch語句中。命名的枚舉變量能夠標記為Java枚舉通過包含enums.swg的擴展,如下:
%module Unix
. . .
/* Java enumeration. */
%include "enums.swg"
/* Named enumeration. */
enum Numbers { ONE = 1, TWO = 2, THREE, FOUR };
package com.apress.swig;
public enum Numbers {
ONE(UnixJNI.ONE_get()),
TWO(UnixJNI.TWO_get()),
THREE,
FOUR;
. . .
/* Helper methods. */
. . .
}
結構體:
? 結構體也被SWIG支持,和他們被定義在接口文件,如下:
?%module Unix
?. . .
?/* Point structure. */
struct Point {
int x;
int y;
};
他們能夠通過getter和setter對于成員變量來封裝,如下:
package com.apress.swig;
public class Point {
private long swigCPtr;
protected boolean swigCMemOwn;
protected Point(long cPtr, boolean cMemoryOwn) {
swigCMemOwn = cMemoryOwn;
swigCPtr = cPtr;
}
protected static long getCPtr(Point obj) {
return (obj == null) ? 0 : obj.swigCPtr;
}
protected void finalize() {
delete();
}
public synchronized void delete() {
if (swigCPtr ! = 0) {
if (swigCMemOwn) {
swigCMemOwn = false;
UnixJNI.delete_Point(swigCPtr);
}
swigCPtr = 0;
}
}
public void setX(int value) {
UnixJNI.Point_x_set(swigCPtr, this, value);
}
public int getX() {
return UnixJNI.Point_x_get(swigCPtr, this);
}
public void setY(int value) {
UnixJNI.Point_y_set(swigCPtr, this, value);
}
public int getY() {
return UnixJNI.Point_y_get(swigCPtr, this);
}
public Point() {
this(UnixJNI.new_Point(), true);
}
}
總結