jni传递数组参数,获取数组的返回值
本文主要介绍java层向jni层传递数组,对数组的内容进行编辑后再返回到java层。
一、jni传递数组参数
1、java层native方法的定义
/*** 传递一个int数组下去,把数组的每一个元素都+1在返回来* @param array*/
public native int[] setIntArray(int []array);
2、jni层的实现
extern "C"
JNIEXPORT jintArray JNICALL
Java_com_hisign_ndktest_MainActivity_setIntArray(JNIEnv *env, jobject thiz, jintArray jarray) {int jLen = env->GetArrayLength(jarray); // 获取java层传递数组的长度LOGI("jLen = %d", jLen);// 该参数设置成 NULL ( 推荐 ) : 表示不关心如何实现 , 让系统自动选择指针生成方式 , 一般情况下都不关心该生成方式jboolean isCopy = NULL; // JNI_TRUE = 1、JNI_FALSE = 0// 将Java的int数组,转为jint数组,返回一个指针指向jint数组首元素地址jint *intArray = env->GetIntArrayElements(jarray, &isCopy); // 第二个参数需要传地址,因为它这里要的是指针for (int i = 0; i < jLen; i++) {LOGI("intArray[%d] = %d", i, *(intArray + i));*(intArray + i) += 1;}// 释放*intArray 后,array会被修改,第三个参数mode有三种取值/*** 0:表示会把缓冲区(即在GetArrayElements方法中返回的)的内容拷贝回原始Java数组中,然后释放缓冲区* JNI_COMMIT:表示也会把缓冲区的内容拷贝回原始Java数组中,但是不会释放缓冲区* JNI_ABORT:表示不会把缓冲区的内容拷贝回原始Java数组中,直接释放缓冲区。*/env->ReleaseIntArrayElements(jarray, intArray, 0);return jarray;
}
3、java层的调用
// 设置int类型的数组到jni中
binding.btnSetIntArray.setOnClickListener(view->{int arr[] = {55,44,33,22,11};int []ret = setIntArray(arr);StringBuilder builder = new StringBuilder();for(int a:ret){builder.append(a +",");Log.d("lixm", "btnSetIntArray: ret a = " + a);}Toast.makeText(this, builder.toString(), Toast.LENGTH_SHORT).show();
});
4、小结:
jni层获取数组的长度,jsize size= env->GetArrayLength(jarray)。
获取指向java层数组的指针,jint *intArray = env->GetIntArrayElements(jarray, &isCopy),通过这个指针可以修改java层的数组。
释放数组 env->ReleaseIntArrayElements(jarray, intArray, 0);把指向Java数组的指针直接在C层处理。处理完本地化的数组后,通过ReleaseIntArrayElements来释放数组。