How to return an array from JNI to Java? How to return an array from JNI to Java? arrays arrays

How to return an array from JNI to Java?


If you've examined the documentation and still have questions that should be part of your initial question. In this case, the JNI function in the example creates a number of arrays. The outer array is comprised of an 'Object' array creating with the JNI function NewObjectArray(). From the perspective of JNI, that's all a two dimensional array is, an object array containing a number of other inner arrays.

The following for loop creates the inner arrays which are of type int[] using the JNI function NewIntArray(). If you just wanted to return a single dimensional array of ints, then the NewIntArray() function is what you'd use to create the return value. If you wanted to create a single dimensional array of Strings then you'd use the NewObjectArray() function but with a different parameter for the class.

Since you want to return an int array, then your code is going to look something like this:

JNIEXPORT jintArray JNICALL Java_ArrayTest_initIntArray(JNIEnv *env, jclass cls, int size){ jintArray result; result = (*env)->NewIntArray(env, size); if (result == NULL) {     return NULL; /* out of memory error thrown */ } int i; // fill a temp structure to use to populate the java int array jint fill[size]; for (i = 0; i < size; i++) {     fill[i] = 0; // put whatever logic you want to populate the values here. } // move from the temp structure to the java structure (*env)->SetIntArrayRegion(env, result, 0, size, fill); return result;}


if someone would like to know how to return String[] array:

java code

private native String[] data();

native export

JNIEXPORT jobjectArray JNICALL Java_example_data() (JNIEnv *, jobject);

native code

  JNIEXPORT jobjectArray JNICALL                  Java_example_data    (JNIEnv *env, jobject jobj){      jobjectArray ret;      int i;      char *message[5]= {"first",                          "second",                          "third",                          "fourth",                          "fifth"};      ret= (jobjectArray)env->NewObjectArray(5,           env->FindClass("java/lang/String"),           env->NewStringUTF(""));      for(i=0;i<5;i++) {          env->SetObjectArrayElement(          ret,i,env->NewStringUTF(message[i]));      }      return(ret);    }  

from link:http://www.coderanch.com/t/326467/java/java/Returning-String-array-program-Java


Based on the asked question, this is already explained in the first answer that how can we pass int[] via jobjectArray. But Here is an example how we can return a jobjectArray which contains lists of data. This can be helpful for situations for example: when someone needs to return data in 2D format to draw some line with x and y points. The below example shows how a jobjectArray can return data in the form of following format:

Java input to the JNI:
Array[Arraylist of x float points][Arraylist of y float points]

JNI output to java:
jobjectArray[Arraylist of x float points] [Arraylist of y float points]

    extern "C" JNIEXPORT jobjectArray JNICALL        _MainActivity_callOpenCVFn(                JNIEnv *env, jobject /* this */,                jobjectArray list) {         //Finding arrayList class and float class(2 lists , one x and another is y)            static jclass arrayListCls = static_cast<jclass>(env->NewGlobalRef(env->FindClass("java/util/ArrayList")));            jclass floatCls = env->FindClass("java/lang/Float");         //env initialization of list object and float            static jmethodID listConstructor = env->GetMethodID(arrayListCls, "<init>", "(I)V");            jmethodID alGetId  = env->GetMethodID(arrayListCls, "get", "(I)Ljava/lang/Object;");            jmethodID alSizeId = env->GetMethodID(arrayListCls, "size", "()I");            static jmethodID addElementToList = env->GetMethodID(arrayListCls, "add", "(Ljava/lang/Object;)Z");            jmethodID floatConstructor = env->GetMethodID( floatCls, "<init>", "(F)V");            jmethodID floatId = env->GetMethodID(floatCls,"floatValue", "()F");        //null check(if null then return)        if (arrayListCls == nullptr || floatCls == nullptr) {            return 0;        }    //     Get the value of each Float list object in the array        jsize length = env->GetArrayLength(list);        //If empty        if (length < 1) {            env->DeleteLocalRef(arrayListCls);            env->DeleteLocalRef(floatCls);            return 0;        }// Creating an output jObjectArray    jobjectArray outJNIArray = env->NewObjectArray(length, arrayListCls, 0);        //taking list of X and Y points object at the time of return        jobject  xPoint,yPoint,xReturnObject,yReturnObject;            //getting the xList,yList object from the array            jobject xObjFloatList = env->GetObjectArrayElement(list, 0);            jobject yObjFloatList = env->GetObjectArrayElement(list, 1);     // number of elements present in the array object        int xPointCounts = static_cast<int>(env->CallIntMethod(xObjFloatList, alSizeId));        static jfloat xReturn, yReturn;                jobject xReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);        jobject yReturnArrayList = env->NewObject(arrayListCls,listConstructor,0);    for (int j = 0; j < xPointCounts; j++) {            //Getting the x points from the x object list in the array            xPoint = env->CallObjectMethod(xObjFloatList, alGetId, j);            //Getting the y points from the y object list in the array            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`)              //float x and y values            xReturn =static_cast<jfloat >(env->CallFloatMethod(xPoint, floatId,j));            yReturn =static_cast<jfloat >(env->CallFloatMethod(yPoint, floatId,j));            xReturnObject = env->NewObject(floatCls,floatConstructor,xReturn);             yReturnObject = env->NewObject(floatCls,floatConstructor,yReturn);            env->CallBooleanMethod(xReturnArrayList,addElementToList,xReturnObject);            env->CallBooleanMethod(yReturnArrayList,addElementToList,yReturnObject);            env->SetObjectArrayElement(outJNIArray,0,xReturnArrayList);            env->SetObjectArrayElement(outJNIArray,1,yReturnArrayList);        __android_log_print(ANDROID_LOG_ERROR, "List of X and Y are saved in the array","%d", 3);    }    return outJNIArray;