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;
}
I've made a simple function for conversion:
jobjectArray getJNIArray(JNIEnv *env, jobject obj, const vector<vector<float> >& arr) {
jclass floatClass = env->FindClass("[F"); //
jsize height = arr.size();
// Create the returnable 2D array
jobjectArray jObjarray = env->NewObjectArray(height, floatClass, NULL);
// Go through the first dimension and add the second dimension arrays
for (unsigned int i = 0; i < height; i++) {
jfloatArray floatArray = env->NewFloatArray(arr[i].size());
env->SetFloatArrayRegion(floatArray, (jsize) 0, (jsize) arr[i].size(), (jfloat*) arr[i].data());
env->SetObjectArrayElement(jObjarray, (jsize) i, floatArray);
env->DeleteLocalRef(floatArray);
}
return jObjarray;
}