How to return an array from JNI to Java?
Solution 1
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;
}
Solution 2
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
Comments
-
RyanCheu over 4 years
I am attempting to use the android NDK.
Is there a way to return an array (in my case an
int[]
) created in JNI to Java? If so, please provide a quick example of the JNI function that would do this.-Thanks
-
RyanCheu over 14 yearsYeah, I did that already. I was having trouble understanding the example that was related to my problem ( the last one ), and I was wondering if someone would mind explaining a simpler example with just returning an int[].
-
RyanCheu over 14 yearsEDIT: Please ignore my previous comment, the above code does work. Thank you! That was very helpful.
-
RyanCheu over 14 yearsEDIT2: The code works, but you have to change tmp in the SetIntArrayRegion(...) to fill.
-
Tobi Akinyemi about 3 yearsDon't you get a NPE when you go out of scope - as
fill
is destructed. or doesSetIntArrayRegion
immediately copy the data? -
Tobi Akinyemi about 3 yearsGreat solution!
-
Jherico about 3 yearsPer the JNI documentation, the SetIntArrayRegion and all the similar primitive array population functions copy data into the JNI managed structure. The
fill
array only needs to be valid for the duration of the function. -
Umair almost 3 years@Jherico, can you guide about the size variable. I mean the line "result = (*env)->NewIntArray(env, size);", and if we don't know how much size C array will throw back. Can we somehow get the size of incoming array.
-
Jherico about 2 years@Umair In C an array is just a pointer. Any function that takes a pointer to an array of values must also be passed a size value as a separate parameter. There are numerous examples in the standard C library, such as
memset
. -
Farrukh Nabiyev about 2 yearsThanks. I could not understand what is a buffer* in the SetIntArrayRegion method call. Now I see that it is an array.
-
Wade Wang almost 2 yearsCurrently in 2022, we should use
env->
instead of(*env)->
.