(原文來自:
2006-06-18 嘗試了一下用 swig 編寫 JNI 程序)
總是覺得編寫 JNI (Java Native Interface) 程序是件復雜的事情, 于是開始漫無目的地搜索是否有簡單一點的方法, 倒是有些商業軟件提供這樣的功能, 比如 http://www.jniwrapper.com 就提供了通過 Java 直接調用 DLL 的功能(可惜是商業軟件, 哈哈).
搜索中無意到了 swig 的網站( http://www.swig.org ), 看到一個用 swig 產生 Java 模塊的例子(原來知道 swig 是因為 python 的緣故), 于是就照著例子自己嘗試了一下(比例子稍微復雜一點, 另外我是用 mingw 上的 gcc 進行編譯的).
源代碼包括 3 個文件, Example.c, Example.i, net/thinkbase/test/Test.java
:
/**?Example.c?****************************************************************/
#include?<time.h>
/**A?variable*/
double?
PI?=?
3.1415927
;
/**Return?n!*/
int?
fact
(
int?
n
)?{
????
if?
(
n?<=?
1
)
????????
return?
1
;
????
else
????????
return?
n*fact
(
n-
1
)
;
}
/**mod?function*/
int?
mod
(
int?
x,?
int?
y
)?{
????
return?
(
x%y
)
;
}
/**Get?time?as?String*/
char?
*?getTime
(){
????
time_t?ltime;
????
time
(
<ime
)
;
????
return?
ctime
(
<ime
)
;
}
/**to?upper?case*/
char?
*?toUpperCase
(
char?
*?result
){
????
char?
*?p?=?result;
????
while
(
'\0'
!=*p
){
????????
char?
c?=?*p;
????????
if?
(?(
c?>?
'a'
)
&&
(
c?<?
'x'
)?){
????????
*p?=?c-
32
;
????????
}
????????
p++;
????
}
????
return?
result;
}
|
/**?Example.i?****************************************************************/
%module?Example
%
{
????
/*?Put?header?files?here?or?function?declarations?like?below?*/
????
extern?
double?
PI;
????
extern?
int?
fact
(
int?
n
)
;
????
extern?
int?
mod
(
int?
x,?
int?
y
)
;
????
extern?
char?
*?getTime
()
;
????
extern?
char?
*?toUpperCase
(
char?
*?str
)
;
%
}
extern?
double?
PI;
extern?
int?
fact
(
int?
n
)
;
extern?
int?
mod
(
int?
x,?
int?
y
)
;
extern?
char?
*?getTime
()
;
extern?
char?
*?toUpperCase
(
char?
*?str
)
;
|
/**?net/thinkbase/test/Test.java?*********************************************/
package?
net.thinkbase.test;
import?
net.thinkbase.test.swig.Example;
public?class?
Test?
{
????
public?static?
void?
main
(
String?argv
[])?{
????????
System.loadLibrary
(
"Example"
)
;
????????
System.out.println
(
????????????
"????Example.getPI()??????=?"?
+?Example.getPI
())
;
????????
System.out.println
(
????????????
"????Example.fact(6)??????=?"?
+?Example.fact
(
6
))
;
????????
System.loadLibrary
(
"Example"
)
;
????????
System.out.println
(
????????????
"????Example.mod(100,?30)?=?"?
+?Example.mod
(
100
,?
30
))
;
????????
System.out.println
(
????????????
"????Example.getTime()????=?"?
+?Example.getTime
())
;
????????
System.out.println
(
????????????
"????Example.toUpperCase(\"Hello,?world!\")?=?"?
+
????????????
Example.toUpperCase
(
"Hello,?world!"
))
;
????
}
}
|
試驗步驟
建立必要的目錄:
mkdir "net/thinkbase/test/swig"
mkdir ".out"
使用 swig 建立相關接口:
swig -java -package net.thinkbase.test.swig -outdir net/thinkbase/test/swig Example.i
編譯 c 文件得到 dll:
gcc -c Example.c -o .out/Example.o -I%JAVA_HOME%/include -I%JAVA_HOME%/include/win32
gcc -c Example_wrap.c -o .out/Example_wrap.o -I%JAVA_HOME%/include -I%JAVA_HOME%/include/win32
gcc -shared .out/Example.o .out/Example_wrap.o -mno-cygwin -Wl,--add-stdcall-alias -o .out/Example.dll
編譯測試用的 Java 程序:
javac -sourcepath . net/thinkbase/test/Test.java -d .out
運行測試:
java -cp .out -Djava.library.path=.out net.thinkbase.test.Test
運行及測試結果:
源代碼可以從這里下載: