如何将数组从JNI返回到Java?

我正在尝试使用android NDK。


有没有办法将int[]在JNI中创建的数组(以我的情况为例)返回给Java?如果是这样,请提供一个可以执行此操作的JNI函数的简单示例。


-谢谢


慕容森
浏览 2400回答 3
3回答

繁星点点滴滴

如果您已经阅读了文档,但仍然有一些问题应作为最初问题的一部分。在这种情况下,示例中的JNI函数将创建多个数组。外部数组由使用JNI函数创建的“对象”数组组成NewObjectArray()。从JNI的角度来看,这就是一个二维数组,一个包含多个其他内部数组的对象数组。以下for循环使用JNI函数创建类型为int []的内部数组NewIntArray()。如果您只想返回一个一维整数数组,则NewIntArray()可以使用该函数来创建返回值。如果要创建字符串的一维数组,则可以使用该NewObjectArray()函数,但为该类使用不同的参数。由于您要返回一个int数组,因此您的代码将如下所示:JNIEXPORT jintArray JNICALL Java_ArrayTest_initIntArray(JNIEnv *env, jclass cls, int size){&nbsp;jintArray result;&nbsp;result = (*env)->NewIntArray(env, size);&nbsp;if (result == NULL) {&nbsp; &nbsp; &nbsp;return NULL; /* out of memory error thrown */&nbsp;}&nbsp;int i;&nbsp;// fill a temp structure to use to populate the java int array&nbsp;jint fill[size];&nbsp;for (i = 0; i < size; i++) {&nbsp; &nbsp; &nbsp;fill[i] = 0; // put whatever logic you want to populate the values here.&nbsp;}&nbsp;// move from the temp structure to the java structure&nbsp;(*env)->SetIntArrayRegion(env, result, 0, size, fill);&nbsp;return result;}

偶然的你

基于提出的问题,这已经在第一个答案中得到了解释,即如何通过jobjectArray传递int []。但是这是一个示例,我们如何返回包含数据列表的jobjectArray。例如,这在某些情况下很有用:当某人需要返回2D格式的数据以绘制带有x和y点的线时。以下示例显示jobjectArray如何以以下格式的形式返回数据:Java输入到JNI:Array [ Arraylistof x float points] [ Arraylistof y float points]JNI输出到Java:jobjectArray[ Arraylist个x浮点数] [ Arraylist个y浮点数]&nbsp; &nbsp; extern "C" JNIEXPORT jobjectArray JNICALL&nbsp; &nbsp; &nbsp; &nbsp; _MainActivity_callOpenCVFn(&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; JNIEnv *env, jobject /* this */,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobjectArray list) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//Finding arrayList class and float class(2 lists , one x and another is y)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; static jclass arrayListCls = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jclass floatCls = env->FindClass("java/lang/Float");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;//env initialization of list object and float&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; static jmethodID listConstructor = env->GetMethodID(arrayListCls, "<init>", "(I)V");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmethodID alGetId&nbsp; = env->GetMethodID(arrayListCls, "get", "(I)Ljava/lang/Object;");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmethodID alSizeId = env->GetMethodID(arrayListCls, "size", "()I");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; static jmethodID addElementToList = env->GetMethodID(arrayListCls, "add", "(Ljava/lang/Object;)Z");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmethodID floatConstructor = env->GetMethodID( floatCls, "<init>", "(F)V");&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jmethodID floatId = env->GetMethodID(floatCls,"floatValue", "()F");&nbsp; &nbsp; &nbsp; &nbsp; //null check(if null then return)&nbsp; &nbsp; &nbsp; &nbsp; if (arrayListCls == nullptr || floatCls == nullptr) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; //&nbsp; &nbsp; &nbsp;Get the value of each Float list object in the array&nbsp; &nbsp; &nbsp; &nbsp; jsize length = env->GetArrayLength(list);&nbsp; &nbsp; &nbsp; &nbsp; //If empty&nbsp; &nbsp; &nbsp; &nbsp; if (length < 1) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->DeleteLocalRef(arrayListCls);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->DeleteLocalRef(floatCls);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; return 0;&nbsp; &nbsp; &nbsp; &nbsp; }// Creating an output jObjectArray&nbsp; &nbsp; jobjectArray outJNIArray = env->NewObjectArray(length, arrayListCls, 0);&nbsp; &nbsp; &nbsp; &nbsp; //taking list of X and Y points object at the time of return&nbsp; &nbsp; &nbsp; &nbsp; jobject&nbsp; xPoint,yPoint,xReturnObject,yReturnObject;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //getting the xList,yList object from the array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobject xObjFloatList = env->GetObjectArrayElement(list, 0);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobject yObjFloatList = env->GetObjectArrayElement(list, 1);&nbsp; &nbsp; &nbsp;// number of elements present in the array object&nbsp; &nbsp; &nbsp; &nbsp; int xPointCounts = static_cast<int>(env->CallIntMethod(xObjFloatList, alSizeId));&nbsp; &nbsp; &nbsp; &nbsp; static jfloat xReturn, yReturn;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; jobject xReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);&nbsp; &nbsp; &nbsp; &nbsp; jobject yReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);&nbsp; &nbsp; for (int j = 0; j < xPointCounts; j++) {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Getting the x points from the x object list in the array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xPoint = env->CallObjectMethod(xObjFloatList, alGetId, j);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //Getting the y points from the y object list in the array&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yPoint = env->CallObjectMethod(yObjFloatList, alGetId, j);//Returning jobjectArray(Here I am returning the same x and points I am receiving from java side, just to show how to make the returning `jobjectArray`)&nbsp;&nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; //float x and y values&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xReturn =static_cast<jfloat >(env->CallFloatMethod(xPoint, floatId,j));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; yReturn =static_cast<jfloat >(env->CallFloatMethod(yPoint, floatId,j));&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; xReturnObject = env->NewObject(floatCls,floatConstructor,xReturn);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;yReturnObject = env->NewObject(floatCls,floatConstructor,yReturn);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->CallBooleanMethod(xReturnArrayList,addElementToList,xReturnObject);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->CallBooleanMethod(yReturnArrayList,addElementToList,yReturnObject);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->SetObjectArrayElement(outJNIArray,0,xReturnArrayList);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; env->SetObjectArrayElement(outJNIArray,1,yReturnArrayList);&nbsp; &nbsp; &nbsp; &nbsp; __android_log_print(ANDROID_LOG_ERROR, "List of X and Y are saved in the array","%d", 3);&nbsp; &nbsp; }&nbsp; &nbsp; return outJNIArray;
打开App,查看更多内容
随时随地看视频慕课网APP