【JNI】辨析GettypeElement和GettypeRegion
程序员文章站
2023-12-27 15:47:09
...
辨析GetArrayElement和GetArrayRegion
1. 简介
为了叙述方便,以int类型数组举例子:
-
GetIntArrayRegion
表示 把Java的数组拷贝到 C++新建的数组内存区域中 -
GetIntArrayElements
表示把C++的一个数组指针指向 Java的数组,这样C++修改数组后,Java的变量是会发生改变的。
2. GetIntArrayRegion
由于GetIntArrayRegion是拷贝到C++新建的数组内存中,所以必须先准备好一段数组内存空间,
// 输入 jintArray int_array
int intArrInCPP[10];
// 参数表示 复制的起始位置和长度。
env->GetIntArrayRegion(int_array,0,10,intArrInCPP);
intArrInCPP[0]=-1;
当我们在C++中对数组做出修改后,由于不是同一块内存,所以Java中的值不会被改变。
优点
- C++中的改变不会影响Java中的数值
不用通过返回值,既可以在Java中看到修改后的结果
优点:
- 不用拷贝占用额外的内存,Java和C++中的改版是同步的
2 GetIntArrayElements
jint* nativeArray;
jboolean isCopy;
naticeArray = env->GetIntArrayElements(javaArray,&iscopy);
GetIntArrayElements 允许 C++代码得到一个指向Java数组内存的指针
参数isCopy
- =true: 则指针指向的是一个数组的拷贝
- = false:指向的是Java的堆内存地址。
但是要想使GetIntArrayElements的改动让Java层收到,还需要释放掉c++中的指针,否则将会内存泄漏。
// 释放指针
env->ReleaseIntArrayElements(javaArray,nativeArray,RELEASE_MODE);
根据释放的模式参数 RELEASE_MODE,释放的方式有三种:
-
=0 ,把数组内容拷贝回去,并且释放C++内存
-
=JNI_COMMIT 把数组内容拷贝回去,但不释放C++内存。
-
= JNI_ABORT 不拷贝数组内容,只释放内存。
所以
int* intArrInCPP;
jboolean isCopy[1];
isCopy[0]= true;
intArrInCPP= env->GetIntArrayElements(int_array,isCopy);
intArrInCPP[0]=121;
__android_log_print(ANDROID_LOG_ERROR,"SSSS",":%d,%d",intArrInCPP,&int_array);
env->ReleaseIntArrayElements(int_array,intArrInCPP,0);
I 附加:
C++ 中的Android log使用格式化字符串输入。
__android_log_print(ANDROID_LOG_ERROR,"SSSS","intArrInCPP:%d\tint_array%d",intArrInCPP,&int_array);