SWIG小例子
這個Android平臺式建立在Linux OS平臺上的,是一個多用戶平臺。
它運行的應用程序在一個虛擬機sandbox和把他們當做不同的用戶
來讓平臺安全。在Linux上,每一個用戶都分配一個用戶ID,和用戶ID
能夠被PoSIX os API的getuid函數訪問。作為一個獨立的平臺編程語言,
Java并不能提供獲得這些函數。作為這個例子程序的一部分,
? ? 1.寫一個Swig接口文件來訪問這個getuid函數
? ? 2.整合swig到Android建立進程中。
? ? 3.增加SWig產生的源文件到Android.mk建立文件
? ? 4.使用者SWIG產生的代理類來詢問這getuid
? ? 5.展示結果到屏幕上
接口文件:
? ? swig接口文件包含函數原型,類和變量的定義。它的語法和普通
的c/c++頭文件一樣。除了c/c++關鍵字和預處理命令,這個接口文件
也能夠包含SWIG指定的預處理指令(能夠調節產生的封裝代碼);
? ? 為了獲得getuid,一個接口文件(unix.i)需要被定義。
? ? /* Module name is Unix. */
? ? ?%module Unix
? ? ?%{
? ? ? ? ? /* Include the POSIX operating system APIs. */
? ? ? ? ? #include < unistd.h>
? ? ?%}
? 模塊名:
? 每一個調用的SWIG都需要指定一個模塊名。這個模塊名被用來命名
結果封裝的文件。這個模塊名被指定使用SWIG指定的預處理命令%module
和它應該出現在每個接口文件的開始處。
? ?用戶定義的代碼:
? SWIG僅僅使用這個接口文件當產生封裝代碼;它的內容沒有超出這個
點。它是需要包含用戶定義的代碼在產生的文件中,例如任何需要編譯
這個產生代碼的頭文件。當SWIG產生一個封裝的代碼時,它被分成5部分
。SWIG提供預處理命令來使開發者來指定代碼片段應該包含在這些5部分
。
? % < section > %{
? . . .
? This code block will be included into generated code as is.
? . . .
? %}
這<section>部分能夠取得值:
? ? ?begin:放在代碼塊在產生封裝文件的開始出。它主要用來定義預處理
的宏。
? ? ?runtime:放代碼塊在SWIG的內部類型檢測和其他支持函數處。
? ? ?header:放代碼塊到頭文件部分和其他的幫助函數。可以省略
? ? ?wrapper:放在代碼塊緊靠在產生封裝函數處。
? ? ?init:在加載時,放置代碼塊到初始模塊的函數處。
類型定義:
? SWIG能夠理解所有C/C++數據類型,但是把其他都當做對象和封裝
他們作為指針。getuid函數的定義建議,它的返回值是uid_t,這并
不是一個標準的c/c++數據類型。SWIG將把它當做一個對象和將包裝
為一個指針。這并不是優先的旋轉,實際上uid_t是unsigned integer
,并不是一個對象。如下unix.i接口文件,使用typedef來告訴SWIG
getuid函數的真實類型。
? /* Tell SWIG about uid_t. */
? typedef unsigned int uid_t;
?函數原型:
? 這個unix.i接口文件以getuid函數的原型結尾,如下
? ?uind_t getuid();
?產生Java的包對于代理類:
? New-package-com.appress.swig
?出發Swig:
? swig -java -package com.apress.swig?
-outdir src/com/apress/swig jni/Unix.ion the command line.
?產生文件jni下產生Unix_wrap.c和包下的UnixJNI.java和代理類
Unix.java在包com.apress.swig.
? 整合SWIG到Android 建立進程
? 建立Andoid建立片段為SWIG,new-file-my-swig-genrate.mk
? #
# SWIG extension for Android build system.
#
# @author Onur Cinar
#
# Check if the MY_SWIG_PACKAGE is defined
ifndef MY_SWIG_PACKAGE
$(error MY_SWIG_PACKAGE is not defined.)
endif
# Replace dots with slashes for the Java directory
MY_SWIG_OUTDIR := $(NDK_PROJECT_PATH)/src/$(subst .,/,$(MY_SWIG_PACKAGE))
. . .
# Default SWIG type is C
ifndef MY_SWIG_TYPE
MY_SWIG_TYPE := c
endif
# Set SWIG mode
ifeq ($(MY_SWIG_TYPE),cxx)
MY_SWIG_MODE := ? c++
else
MY_SWIG_MODE :=
endif
# Append SWIG wrapper source files
+ = $(foreach MY_SWIG_INTERFACE,\
$(MY_SWIG_INTERFACES),\
$(basename $(MY_SWIG_INTERFACE))_wrap.$(MY_SWIG_TYPE))
+ = .cxx
$(call host-mkdir,$(MY_SWIG_OUTDIR))
swig -java \
$(MY_SWIG_MODE) \
-package $(MY_SWIG_PACKAGE) \
-outdir $(MY_SWIG_OUTDIR) \
$<
整合SWIG到Android.mk
?為了使用這個建立系統片元,這個村子的Android.mk文件需要被修改。
這個建立系統編譯需要三個新的變量被定義在Android.mk文件
? ?MY_SWIG_PACKAGE:定義這個SWIG產生代理類的Java包。在這個例子
中是com.apress.swig.package
? ?MY_SWIG_INTERFACES:應該被處理的SWIG接口文件的列表。在這個例子中
是Unix.i文件。
? ?MY_SWIG_MODE:命令SWIG產生的封裝代碼是C或者是C++,在這個例子中
是C代碼。
? ?LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
MY_SWIG_PACKAGE := com.apress.swig
MY_SWIG_INTERFACES := Unix.i
MY_SWIG_TYPE := c
include $(LOCAL_PATH)/my-swig-generate.mk
include $(BUILD_SHARED_LIBRARY)
?
它運行的應用程序在一個虛擬機sandbox和把他們當做不同的用戶
來讓平臺安全。在Linux上,每一個用戶都分配一個用戶ID,和用戶ID
能夠被PoSIX os API的getuid函數訪問。作為一個獨立的平臺編程語言,
Java并不能提供獲得這些函數。作為這個例子程序的一部分,
? ? 1.寫一個Swig接口文件來訪問這個getuid函數
? ? 2.整合swig到Android建立進程中。
? ? 3.增加SWig產生的源文件到Android.mk建立文件
? ? 4.使用者SWIG產生的代理類來詢問這getuid
? ? 5.展示結果到屏幕上
接口文件:
? ? swig接口文件包含函數原型,類和變量的定義。它的語法和普通
的c/c++頭文件一樣。除了c/c++關鍵字和預處理命令,這個接口文件
也能夠包含SWIG指定的預處理指令(能夠調節產生的封裝代碼);
? ? 為了獲得getuid,一個接口文件(unix.i)需要被定義。
? ? /* Module name is Unix. */
? ? ?%module Unix
? ? ?%{
? ? ? ? ? /* Include the POSIX operating system APIs. */
? ? ? ? ? #include < unistd.h>
? ? ?%}
? 模塊名:
? 每一個調用的SWIG都需要指定一個模塊名。這個模塊名被用來命名
結果封裝的文件。這個模塊名被指定使用SWIG指定的預處理命令%module
和它應該出現在每個接口文件的開始處。
? ?用戶定義的代碼:
? SWIG僅僅使用這個接口文件當產生封裝代碼;它的內容沒有超出這個
點。它是需要包含用戶定義的代碼在產生的文件中,例如任何需要編譯
這個產生代碼的頭文件。當SWIG產生一個封裝的代碼時,它被分成5部分
。SWIG提供預處理命令來使開發者來指定代碼片段應該包含在這些5部分
。
? % < section > %{
? . . .
? This code block will be included into generated code as is.
? . . .
? %}
這<section>部分能夠取得值:
? ? ?begin:放在代碼塊在產生封裝文件的開始出。它主要用來定義預處理
的宏。
? ? ?runtime:放代碼塊在SWIG的內部類型檢測和其他支持函數處。
? ? ?header:放代碼塊到頭文件部分和其他的幫助函數。可以省略
? ? ?wrapper:放在代碼塊緊靠在產生封裝函數處。
? ? ?init:在加載時,放置代碼塊到初始模塊的函數處。
類型定義:
? SWIG能夠理解所有C/C++數據類型,但是把其他都當做對象和封裝
他們作為指針。getuid函數的定義建議,它的返回值是uid_t,這并
不是一個標準的c/c++數據類型。SWIG將把它當做一個對象和將包裝
為一個指針。這并不是優先的旋轉,實際上uid_t是unsigned integer
,并不是一個對象。如下unix.i接口文件,使用typedef來告訴SWIG
getuid函數的真實類型。
? /* Tell SWIG about uid_t. */
? typedef unsigned int uid_t;
?函數原型:
? 這個unix.i接口文件以getuid函數的原型結尾,如下
? ?uind_t getuid();
?產生Java的包對于代理類:
? New-package-com.appress.swig
?出發Swig:
? swig -java -package com.apress.swig?
-outdir src/com/apress/swig jni/Unix.ion the command line.
?產生文件jni下產生Unix_wrap.c和包下的UnixJNI.java和代理類
Unix.java在包com.apress.swig.
? 整合SWIG到Android 建立進程
? 建立Andoid建立片段為SWIG,new-file-my-swig-genrate.mk
? #
# SWIG extension for Android build system.
#
# @author Onur Cinar
#
# Check if the MY_SWIG_PACKAGE is defined
ifndef MY_SWIG_PACKAGE
$(error MY_SWIG_PACKAGE is not defined.)
endif
# Replace dots with slashes for the Java directory
MY_SWIG_OUTDIR := $(NDK_PROJECT_PATH)/src/$(subst .,/,$(MY_SWIG_PACKAGE))
. . .
# Default SWIG type is C
ifndef MY_SWIG_TYPE
MY_SWIG_TYPE := c
endif
# Set SWIG mode
ifeq ($(MY_SWIG_TYPE),cxx)
MY_SWIG_MODE := ? c++
else
MY_SWIG_MODE :=
endif
# Append SWIG wrapper source files
+ = $(foreach MY_SWIG_INTERFACE,\
$(MY_SWIG_INTERFACES),\
$(basename $(MY_SWIG_INTERFACE))_wrap.$(MY_SWIG_TYPE))
+ = .cxx
$(call host-mkdir,$(MY_SWIG_OUTDIR))
swig -java \
$(MY_SWIG_MODE) \
-package $(MY_SWIG_PACKAGE) \
-outdir $(MY_SWIG_OUTDIR) \
$<
整合SWIG到Android.mk
?為了使用這個建立系統片元,這個村子的Android.mk文件需要被修改。
這個建立系統編譯需要三個新的變量被定義在Android.mk文件
? ?MY_SWIG_PACKAGE:定義這個SWIG產生代理類的Java包。在這個例子
中是com.apress.swig.package
? ?MY_SWIG_INTERFACES:應該被處理的SWIG接口文件的列表。在這個例子中
是Unix.i文件。
? ?MY_SWIG_MODE:命令SWIG產生的封裝代碼是C或者是C++,在這個例子中
是C代碼。
? ?LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
MY_SWIG_PACKAGE := com.apress.swig
MY_SWIG_INTERFACES := Unix.i
MY_SWIG_TYPE := c
include $(LOCAL_PATH)/my-swig-generate.mk
include $(BUILD_SHARED_LIBRARY)
?
總結