Java本機(jī)接口
Java本機(jī)接口(Java Native Interface,JNI)是供JVM調(diào)用本地動態(tài)鏈接庫中方法的機(jī)制,一些計算密集的代碼,可以轉(zhuǎn)移到C++實現(xiàn),速度會快很多,而一些硬件通信的功能也只能依靠JNI來實現(xiàn)。但是JNI會破壞Java的跨平臺特性,而且數(shù)據(jù)在JVM和本機(jī)之間的通信過程也會一定程度上拖慢速度。
1 ?DLL調(diào)用
Java代碼中,本地代碼的入口需要單獨放在一個類中,作為靜態(tài)函數(shù)使用,聲明為native方法,如:
然后編寫C++實現(xiàn)代碼:
jni.h(位于JDK安裝目錄下的include文件夾)中提供了JNI數(shù)據(jù)類型的定義。注意函數(shù)名必須為Java_類命名空間_類名_方法名的形式,第1、2個參數(shù)必須分別為JNIEnv和jobject類型,其它參數(shù)和Java代碼中的聲明保持一致。如果用C++編譯器,必須以C語言規(guī)則導(dǎo)出這些函數(shù)。
2 ?字符串
C/C++的字符串默認(rèn)是MBCS編碼的,而Java默認(rèn)是UTF-16編碼,且位于JVM的托管空間下,因此必須進(jìn)行一個轉(zhuǎn)換。如下代碼創(chuàng)建Java字符串:
而下面的代碼讀取從JVM中傳入的字符串。注意,傳入的字符串需要復(fù)制后才能使用,這個副本需要在本機(jī)代碼中釋放內(nèi)存!
3 ?數(shù)組
本機(jī)代碼中不能為Java數(shù)組申請內(nèi)存,只能修改其內(nèi)容,必須由JVM創(chuàng)建并傳入本機(jī)代碼。Java用jarray代表所有類型的數(shù)組,由于Java中所有的數(shù)據(jù)都是對象,所以jintArray和jarray實際上是同一個東西。首先使用JNIEnv::GetArrayLength獲取數(shù)組長度,然后用SetXXXArrayRegion設(shè)定XXX類型數(shù)組的值: