How to Return an Array from Jni to Java

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;
}

How to return an array from JNI to Java in Android?

Take a look here to see how to handle arrays in JNI. This sample will show you how to pass array back and forth:

http://jnicookbook.owsiak.org/recipe-No-013/

Note that you don't want to return the values as function result. When you release with JNI_COMMIT, values are available in the object you have passed as argument.

How to return int array from Java to JNI

Use CallObjectMethod. For example:

jmethodID myMethod = (*env)->GetMethodID(myClass, "myMethod", "()[I");
jintArray retval = (jintArray) (*env)->CallObjectMethod(myObject, myMethod);

How to call a C++ method returning an array from JNI and convert the contents of the array to an array of java classes?

Isn't this what you're after? How to return an array from JNI to Java?

Here are some more detailed examples: https://www3.ntu.edu.sg/home/ehchua/programming/java/JavaNativeInterface.html#zz-6.2

If you want to create the Java objects from JNI code, that's particularly painful. Something like this:

jclass cls = (*env)->FindClass(env, "...your class...");
jmethodID ctor = (*env)->GetMethodID(env, cls, "<init>", "...your ctor signature...");
jobject obj = (*env)->NewObject(env, cls, ctor, ...);

Plus you should null-check the return values of all these of course.

After that you can create the Java array and add the item to it:

jobjectArray results = (*env)->NewObjectArray(env, 100, cls, NULL);
(*env)->SetObjectArrayElement(env, results, 0, obj);

Return a 2D primitive array from C to Java from JNI/NDK

Thanks Timo for your help and link. For posterity, I'm adding a complete code set that would go through the process of generating a 2D primitive array consumable by Java, from an existing C 2D primitive array.

// Returns a 2D float array from C to Java
jobjectArray ndk_test_getMy2DArray(JNIEnv* env, jobject thiz, jlong context)
{
// Cast my context reference
MyContextRef contextRef = (MyContextRef) context;

// Get the length for the first and second dimensions
unsigned int length1D = MyContextGet1DLength(contextRef);
unsigned int length2D = MyContextGet2DLength(contextRef);

// Get the 2D float array we want to "Cast"
float** primitive2DArray = MyContextGet2DArray(contextRef);

// Get the float array class
jclass floatArrayClass = (*env)->FindClass(env, "[F");

// Check if we properly got the float array class
if (floatArrayClass == NULL)
{
// Ooops
return NULL;
}

// Create the returnable 2D array
jobjectArray myReturnable2DArray = (*env)->NewObjectArray(env, (jsize) length1D, floatArrayClass, NULL);

// Go through the firs dimension and add the second dimension arrays
for (unsigned int i = 0; i < length1D; i++)
{
jfloatArray floatArray = (*env)->NewFloatArray(env, length2D);
(*env)->SetFloatArrayRegion(env, floatArray, (jsize) 0, (jsize) length2D, (jfloat*) primitive2DArray[i]);
(*env)->SetObjectArrayElement(env, myReturnable2DArray, (jsize) i, floatArray);
(*env)->DeleteLocalRef(env, floatArray);
}

// Return a Java consumable 2D float array
return myReturnable2DArray;
}


Related Topics



Leave a reply



Submit