JAVA通過JNI調用本地方法,本地方法以庫文件的形式存儲(WINDOWS平臺上是DLL文件,UNIX機器上是SO文件)。通過調用本地庫文件的內部方法,JAVA可以實現與本地機器的緊密聯系,調用系統級接口方法。
簡介及應用如下:
首先,JAVA需要做什麽
在JAVA程序中,首先需要在類中聲明被調用庫的名稱,如下所示:
靜態{
system . loadlibrary(" good luck ");
}
這裏庫的擴展名不用寫,是不是DLL之類的由系統來判斷。
還需要對要調用的方法進行局部聲明,關鍵字是native。而且只需要聲明,不需要實現。如下所示:
public native靜態void set(int I);
public native靜態int get();
然後編譯JAVA程序文件生成類,再使用JAVAH命令,JNI就會生成C/C++的頭文件。
例如,程序testdll.java這樣寫道:
公共類testdll
{
靜電
{
system . loadlibrary(" good luck ");
}
public native靜態int get();
public native靜態void set(int I);
公共靜態void main(String[] args)
{
testdll test = new testdll();
test . set(10);
system . out . println(test . get());
}
}
用javac testdll.java編譯它會生成testdll.class..
再次使用javah testdll會在當前目錄下生成testdll.h文件,需要由C/C++程序調用生成所需的庫文件。
二、C/C++需要做什麽
對於生成的。h頭文件,C/C++需要做的就是具體實現它的方法。然後編譯連接成壹個庫文件。然後把庫文件復制到JAVA程序的路徑下,就可以用JAVA調用C/C++實現的函數了。
舉個例子。我們先來看看testdll.h文件的內容:
/*不要編輯此文件-它是機器生成的*/
# include & ltjni.h & gt
testdll類的頭*/
#ifndef _Included_testdll
#define _Included_testdll
#ifdef __cplusplus
外部" C" {
#endif
/*
*類:testdll
*方法:獲取
*簽名:()I
*/
JNI export jint JNI call Java _ testdll _ get
(JNIEnv *,jclass);
/*
*類:testdll
*方法:設置
*簽名:(壹)五
*/
JNI export void JNI call Java _ testdll _ set
(JNIEnv *、jclass、jint);
#ifdef __cplusplus
}
#endif
#endif
在具體實現中,我們只關心兩個函數原型。
jnie export jint JNI call Java _ testdll _ get(jnie NV *,jclass);
和
JNI export void JNI call Java _ testdll _ set(JNI env *、jclass、jint);
這裏,JNIEXPORT和JNICALL是JNI的關鍵字,表示這個函數將被JNI調用。另壹方面,Jint是壹種使JAVA的int類型通過JNI與本地int通信的類型。我們可以睜壹只眼閉壹只眼,把它當作壹個int。函數名是JAVA_加上JAVA程序的包路徑加上函數名。在參數中,我們只需要關心JAVA程序中存在的參數。至於JNIEnv*和jclass,我們壹般不需要接觸。
好了,讓我們用testdll.cpp文件來實現這兩個功能:
#包含" testdll.h "
int I = 0;
JNI export jint JNI call Java _ testdll _ get(JNI env *,jclass)
{
返回I;
}
JNI export void JNI call Java _ testdll _ set(JNI env *、jclass、jint j)
{
I = j;
}
編譯並連接到壹個庫文件。這個例子是在WINDOWS下完成的,生成了壹個DLL文件。並且這個名字應該和JAVA中需要被調用的壹致,這裏是goodluck.dll。
將goodluck.dll復制到testdll.class的目錄下,java testdll將運行它,您可以觀察到結果。