【摘】Java 本機(jī)接口(Java Native Interface (JNI))是一個(gè)本機(jī)編程接口,它是 Java 軟件開(kāi)發(fā)工具箱(Java Software Development Kit (SDK))的一部分。JNI 允許 Java 代碼使用以其它語(yǔ)言(譬如 C 和 C++)編寫(xiě)的代碼和代碼庫(kù)。Invocation API(JNI 的一部分)可以用來(lái)將 Java 虛擬機(jī)(JVM)嵌入到本機(jī)應(yīng)用程序中,從而允許程序員從本機(jī)代碼內(nèi)部調(diào)用 Java 代碼。
☆JNI [Java調(diào)用其他語(yǔ)言]運(yùn)用方向【摘】
1)希望用更低級(jí)、更快的編程語(yǔ)言去實(shí)現(xiàn)對(duì)時(shí)間有嚴(yán)格要求的代碼。
2)希望從 Java 程序訪問(wèn)舊代碼或代碼庫(kù)。
3)需要標(biāo)準(zhǔn) Java 類庫(kù)中不支持的依賴于平臺(tái)的特性。
2)希望從 Java 程序訪問(wèn)舊代碼或代碼庫(kù)。
3)需要標(biāo)準(zhǔn) Java 類庫(kù)中不支持的依賴于平臺(tái)的特性。
☆步驟【摘】
1)編寫(xiě) Java 代碼。從編寫(xiě) Java 類開(kāi)始,這些類執(zhí)行三個(gè)任務(wù):聲明將要調(diào)用的本機(jī)方法;裝入包含本機(jī)代碼的共享庫(kù);然后調(diào)用該本機(jī)方法。
2)編譯 Java 代碼。在使用 Java 類之前,必須成功地將它們編譯成字節(jié)碼。
3)創(chuàng)建 C/C++ 頭文件。C/C++ 頭文件將聲明想要調(diào)用的本機(jī)函數(shù)說(shuō)明。然后,這個(gè)頭文件與 C/C++ 函數(shù)實(shí)現(xiàn)(請(qǐng)參閱步驟 4)一起來(lái)創(chuàng)建共享庫(kù)(請(qǐng)參閱步驟 5)。
4)編寫(xiě) C/C++ 代碼。這一步實(shí)現(xiàn) C 或 C++ 源代碼文件中的函數(shù)。C/C++ 源文件必須包含步驟 3 中創(chuàng)建的頭文件。
5)創(chuàng)建共享庫(kù)文件。從步驟 4 中創(chuàng)建的 C 源代碼文件來(lái)創(chuàng)建共享庫(kù)文件。
6)運(yùn)行 Java 程序。運(yùn)行該代碼,并查看它是否有用。我們還將討論一些用于解決常見(jiàn)錯(cuò)誤的技巧。
2)編譯 Java 代碼。在使用 Java 類之前,必須成功地將它們編譯成字節(jié)碼。
3)創(chuàng)建 C/C++ 頭文件。C/C++ 頭文件將聲明想要調(diào)用的本機(jī)函數(shù)說(shuō)明。然后,這個(gè)頭文件與 C/C++ 函數(shù)實(shí)現(xiàn)(請(qǐng)參閱步驟 4)一起來(lái)創(chuàng)建共享庫(kù)(請(qǐng)參閱步驟 5)。
4)編寫(xiě) C/C++ 代碼。這一步實(shí)現(xiàn) C 或 C++ 源代碼文件中的函數(shù)。C/C++ 源文件必須包含步驟 3 中創(chuàng)建的頭文件。
5)創(chuàng)建共享庫(kù)文件。從步驟 4 中創(chuàng)建的 C 源代碼文件來(lái)創(chuàng)建共享庫(kù)文件。
6)運(yùn)行 Java 程序。運(yùn)行該代碼,并查看它是否有用。我們還將討論一些用于解決常見(jiàn)錯(cuò)誤的技巧。
☆第一步:編寫(xiě)Java代碼

☆第二步:編譯Java代碼
javac JavaCallC.java
☆第三步:創(chuàng)建C頭文件
javah jnidemo.JavaCallC
得到頭文件如下:
得到頭文件如下:

除了 Java 聲明中的一般參數(shù)以外,所有這些函數(shù)的參數(shù)表中都有一個(gè)指向 JNIEnv 和 jobject 的指針。指向 JNIEnv 的指針實(shí)際上是一個(gè)指向函數(shù)指針表的指針,這些函數(shù)提供各種用來(lái)在 C 和 C++ 中操作 Java 數(shù)據(jù)的能力。
jobject 參數(shù)引用當(dāng)前對(duì)象。因此,如果 C 或 C++ 代碼需要引用 Java 函數(shù),則這個(gè) jobject 充當(dāng)引用或指針,返回調(diào)用的 Java 對(duì)象。
jobject 參數(shù)引用當(dāng)前對(duì)象。因此,如果 C 或 C++ 代碼需要引用 Java 函數(shù),則這個(gè) jobject 充當(dāng)引用或指針,返回調(diào)用的 Java 對(duì)象。
☆第四,五步:編寫(xiě)C代碼[Windows下得到DLL]
1)開(kāi)啟VC;
2)新建->Win32 Dynamic-Link Library工程,工程名為libJavaCallC;
3)在Source Files下新建C文件javaCallC.c;
4)在HeaderFiles下引入頭文件jnidemo_JavaCallC.h;
5)配置路徑,在Tools->Options->Directories下加入JAVA的頭文件,例如:
C:\Program Files\Java\jdk1.6.0\include
C:\Program Files\Java\jdk1.6.0\include\win32
不然編譯會(huì)報(bào)錯(cuò)[Cannot open include file: 'jni.h']
2)新建->Win32 Dynamic-Link Library工程,工程名為libJavaCallC;
3)在Source Files下新建C文件javaCallC.c;
4)在HeaderFiles下引入頭文件jnidemo_JavaCallC.h;
5)配置路徑,在Tools->Options->Directories下加入JAVA的頭文件,例如:
C:\Program Files\Java\jdk1.6.0\include
C:\Program Files\Java\jdk1.6.0\include\win32
不然編譯會(huì)報(bào)錯(cuò)[Cannot open include file: 'jni.h']

API和類型對(duì)照請(qǐng)參考后面的參考資料。





☆第六步:運(yùn)行JAVA程序
1)將libJavaCallC.dll放在環(huán)境變量的路徑中;
2)運(yùn)行:java jnidemo.JavaCallC
2)運(yùn)行:java jnidemo.JavaCallC

☆JNI[其他語(yǔ)言調(diào)用JAVA]
1)希望實(shí)現(xiàn)的這部分代碼是平臺(tái)無(wú)關(guān)的,它將用于跨多種平臺(tái)使用的功能。
2)需要在本機(jī)應(yīng)用程序中訪問(wèn)用 Java 語(yǔ)言編寫(xiě)的代碼或代碼庫(kù)。
3)希望從本機(jī)代碼利用標(biāo)準(zhǔn) Java 類庫(kù)
2)需要在本機(jī)應(yīng)用程序中訪問(wèn)用 Java 語(yǔ)言編寫(xiě)的代碼或代碼庫(kù)。
3)希望從本機(jī)代碼利用標(biāo)準(zhǔn) Java 類庫(kù)
☆開(kāi)發(fā)步驟【摘】
1)編寫(xiě) Java 代碼。這個(gè)步驟包含編寫(xiě)一個(gè)或多個(gè) Java 類,這些類實(shí)現(xiàn)(或調(diào)用其它方法實(shí)現(xiàn))您想要訪問(wèn)的功能。
2)編譯 Java 代碼。在能夠使用這些 Java 類之前,必須成功地將它們編譯成字節(jié)碼。
3)編寫(xiě) C/C++ 代碼。這個(gè)代碼將創(chuàng)建和實(shí)例化 JVM,并調(diào)用正確的 Java 方法。
4)運(yùn)行本機(jī) C/C++ 應(yīng)用程序。將運(yùn)行應(yīng)用程序以查看它是否正常工作。我們還將討論一些用于處理常見(jiàn)錯(cuò)誤的技巧。
2)編譯 Java 代碼。在能夠使用這些 Java 類之前,必須成功地將它們編譯成字節(jié)碼。
3)編寫(xiě) C/C++ 代碼。這個(gè)代碼將創(chuàng)建和實(shí)例化 JVM,并調(diào)用正確的 Java 方法。
4)運(yùn)行本機(jī) C/C++ 應(yīng)用程序。將運(yùn)行應(yīng)用程序以查看它是否正常工作。我們還將討論一些用于處理常見(jiàn)錯(cuò)誤的技巧。
☆第一步:編寫(xiě)Java代碼

☆第二步:編譯Java代碼
javac CCallJava.java
☆編寫(xiě)c代碼
1)開(kāi)啟VC
2)新建一個(gè)Win32 Console Application工程,如果建立的是Win32 Application工程會(huì)報(bào)錯(cuò)[LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16]
3)在Source Files下新建文件cCallJava.c
4)將jvm.lib加入到連接中,project->Settings->Link加入jvm.lib,同時(shí)配置Tools->Directories->Library files中加入jvm.lib目錄,例如:
C:\Program Files\Java\jdk1.6.0\lib
5)配置Include路徑,Tools->Directories->Include files加入java的include目錄,例如:
C:\Program Files\Java\jdk1.6.0\include
C:\Program Files\Java\jdk1.6.0\include\win32
2)新建一個(gè)Win32 Console Application工程,如果建立的是Win32 Application工程會(huì)報(bào)錯(cuò)[LIBCD.lib(wincrt0.obj) : error LNK2001: unresolved external symbol _WinMain@16]
3)在Source Files下新建文件cCallJava.c
4)將jvm.lib加入到連接中,project->Settings->Link加入jvm.lib,同時(shí)配置Tools->Directories->Library files中加入jvm.lib目錄,例如:
C:\Program Files\Java\jdk1.6.0\lib
5)配置Include路徑,Tools->Directories->Include files加入java的include目錄,例如:
C:\Program Files\Java\jdk1.6.0\include
C:\Program Files\Java\jdk1.6.0\include\win32

☆執(zhí)行
1)在編譯的exe文件目錄下新建jnidemo文件夾,把CCallJava.class拷貝到此目錄下;
2)執(zhí)行exe文件
2)執(zhí)行exe文件

☆參考資料
JNI的API參考手冊(cè)[中文版]
IBM開(kāi)發(fā)中心JNI教程