2 通过JNI混合使用Java和C++ ----- 访问数组
關于c和cpp實現native方法的一些注釋:
1>? 在jni.h中首先定義了C的實現方式,然后用內聯函數實現了Cpp的實現方式,如下所示:
const char* GetStringUTFChars(jstring str, jboolean *isCopy)?? /* 依賴于C方式實現Cpp */
{
return functions->GetStringUTFChars(this,str,isCopy);?????? /* C實現方式 */
}
因此,在C中可能這樣寫:(*env)->GetStringUTFChars(env, str, NULL); 但在CPP中,我們必須這么寫:env->GetStringUTFChars(str, NULL);
有兩個主要區別:
首先 ---> cpp函數不包含參數JNIEnv* env;
其次 ---> 在cpp實現中,env直接指向包含JNI函數指針的函數表,而在c實現中,env只是指向某個位置,而該位置才包含一個指向函數表的指針,因此必須使用(*env)才能調用JNI函數。
/* jni.h中JNIEnv的定義 */
#ifdef __cplusplus
typedef JNIEnv_ JNIEnv;???????????????????????????????? /* cpp定義 */
#else
typedef const struct JNINativeInterface_ *JNIEnv;?????? /* c定義 */
#endif
?
2>? 關于動態庫的編譯:
如果使用.c文件生成動態庫,則使用gcc編譯:
gcc -Wl,--kill-at –shared –I D:\jdk1.7.0_75\include –I D:\jdk1.7.0_75\include\win32 IntArray.c –o intarray.dll
如果使用.cpp文件生成動態庫,則使用g++編譯:
g++ -Wl,--kill-at –shared –I D:\jdk1.7.0_75\include –I D:\jdk1.7.0_75\include\win32 ObjectArrayTest.cpp –o objectarraytest.dll
?
JNI訪問基本數組時與訪問字符串類似,而且可以通過JNI函數SetIntArrayRegion改變基本數組的值。此外,JNI提供了一系列的Get/Release<Type>ArrayElements函數來操作基本數組,其返回/釋放一個指向(元素本身或其副本)的指針,具體實現由JVM決定,比較安全,如下程序通過native方法計算int型數組的和:
1 // IntArray.java 2 class IntArray 3 { 4 static 5 { 6 System.loadLibrary("intarray"); 7 } 8 private native int SumArray(int[] arr); 9 10 public static void main(String[] args) 11 { 12 IntArray p = new IntArray(); 13 int arr[] = new int[10]; 14 for(int i = 0; i < 10; i++) 15 { 16 arr[i] = i; 17 } 18 int sum = p.SumArray(arr); 19 System.out.println("sum = " + sum); 20 } 21 } 22 23 /***********************************************/ 24 // Intarray.h 25 /* DO NOT EDIT THIS FILE - it is machine generated */ 26 #include <jni.h> 27 /* Header for class IntArray */ 28 29 #ifndef _Included_IntArray 30 #define _Included_IntArray 31 #ifdef __cplusplus 32 extern "C" { 33 #endif 34 /* 35 * Class: IntArray 36 * Method: SumArray 37 * Signature: ([I)I 38 */ 39 JNIEXPORT jint JNICALL Java_IntArray_SumArray 40 (JNIEnv *, jobject, jintArray); 41 42 #ifdef __cplusplus 43 } 44 #endif 45 #endif 46 47 /***********************************************/ 48 // IntArray.c 49 #include "IntArray.h" 50 51 JNIEXPORT jint JNICALL Java_IntArray_SumArray 52 (JNIEnv *env, jobject obj, jintArray arr) 53 { 54 jint buf[10]; 55 jint i, sum = 0; 56 (*env)->GetIntArrayRegion(env, arr, 0, 10, buf); 57 for(i = 0; i < 10; i++) 58 { 59 sum += buf[i]; 60 } 61 return sum; 62 }?
JNI訪問對象數組時使用函數對:Get/SetObjectArrayElement返回/更新指定索引的對象,如下native方法返回一個5*5的二維數組:
1 //ObjectArrayTest.java 2 class ObjectArrayTest 3 { 4 static 5 { 6 System.loadLibrary("objectarraytest"); 7 } 8 private static native int[][] InitInt2DArray(int size); 9 10 public static void main(String[] args) 11 { 12 int[][] int2DArr = InitInt2DArray(5); 13 for(int i = 0; i < 5; i++) 14 { 15 for(int j = 0; j < 5; j++) 16 { 17 System.out.println(int2DArr + " "); 18 } 19 System.out.println(); 20 } 21 } 22 } 23 24 /***********************************************/ 25 // ObjectArrayTest.h 26 class ObjectArrayTest 27 { 28 static 29 { 30 System.loadLibrary("objectarraytest"); 31 } 32 private static native int[][] InitInt2DArray(int size); 33 34 public static void main(String[] args) 35 { 36 int[][] int2DArr = InitInt2DArray(5); 37 for(int i = 0; i < 5; i++) 38 { 39 for(int j = 0; j < 5; j++) 40 { 41 System.out.println(int2DArr + " "); 42 } 43 System.out.println(); 44 } 45 } 46 } 47 48 /***********************************************/ 49 // ObjectArrayTest.cpp 50 #include "ObjectArrayTest.h" 51 52 JNIEXPORT jobjectArray JNICALL Java_ObjectArrayTest_InitInt2DArray 53 (JNIEnv *env, jclass cls, jint size) 54 { 55 jobjectArray result; 56 int i; 57 jclass intArrCls = env->FindClass("[I"); /* "[I" 代表int[] */ 58 if(intArrCls == NULL) 59 { 60 return NULL; 61 } 62 result = env->NewObjectArray(size, intArrCls, NULL); /* result是一個對象數組,其中的元素類型為int[] */ 63 if(result == NULL) 64 { 65 return NULL; 66 } 67 68 for(i = 0; i < size; i++) 69 { 70 jint temp[256]; 71 int j; 72 jintArray intArr = env->NewIntArray(size); /* 創建size個int元素的一維數組 */ 73 if(intArr = NULL) 74 { 75 return NULL; 76 } 77 for(j = 0; j < size; j++) 78 { 79 temp[j] = i + j; 80 } 81 env->SetIntArrayRegion(intArr, 0, size, temp); /* 將temp中的內容復制到intArr中 */ 82 env->SetObjectArrayElement(result, i, intArr); /* 將intArr中的內容復制到result中以便返回 */ 83 env->DeleteLocalRef(intArr); 84 } 85 return result; 86 }?
轉載于:https://www.cnblogs.com/benxintuzi/p/4593437.html
總結
以上是生活随笔為你收集整理的2 通过JNI混合使用Java和C++ ----- 访问数组的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 数1 游戏
- 下一篇: C语言及程序设计进阶例程-32 位运算及