I'm passing an int array from Java to native method. Then within JNI function I created a pointer to int array with GetIntArrayElements() and pass as *isCopy argument JNI_FALSE. I supposed that this will not create a copy of the original array and I could modify array in place. Then I use ReleaseIntArrayElements() and pass as mode argument JNI_ABORT to just relese buffer. But that didn't work.
From JNI documentation:
That when I tried to use mode "0" in ReleaseIntArrayElements() that worked perfectly. But I don't understand why cause I didn't create a copy of the original array and mode "0" is copying back the content.
I suppose that JNI always create a copy of the original array. But then *isCopy argument in GetIntArrayElements() lose its sense. So what really happening with this?
THIS IS MY JNI FUCNTION
extern "C" JNIEXPORT jdouble JNICALL
Java_my_own_package_MainActivity_myFunction(
    JNIEnv *env,
    jobject /* this */, jintArray tbl) {
    jint *tblptr = env->GetIntArrayElements(tbl, JNI_FALSE);
    tblptr[0] = 0; //in-place change
    env->ReleaseIntArrayElements(tb1, tblptr, JNI_ABORT);
    return 0;
}
                You misused the jboolean *isCopy. It is an out parameter you should examine after the actual call to env->GetIntArrayElements(tbl, isCopy);. If it returns JNI_FALSE then the copy is not made.
This is necessary since GC can move elements from one location to another unpredictably and you should always copy the changes back to the original java array. Because you never know the memory location of the actual java array.
If you dont want the copy is made you are probably looking for a critical version of the method. Here is what the JNI docs says:
These restrictions make it more likely that the native code > will obtain an uncopied version of the array, even if the VM > does not support pinning
This does not mean that JVM will disable garbage collection as long as you are holding a critical section although it is likely to do so.
Emp. Mine:
For example, a VM may temporarily disable garbage collection when the native code is holding a pointer to an array obtained via
GetPrimitiveArrayCritical
You seem to have misunderstood the purpose of the isCopy parameter for GetIntArrayElements. It is not an input parameter telling GetIntArrayElements whether it should give you a copy of the array data; it is an output parameter which GetIntArrayElements can use to tell you whether or not it created a copy.
From the documentation:
If isCopy is not NULL, then *isCopy is set to JNI_TRUE if a copy is made; or it is set to JNI_FALSE if no copy is made.
So, if you pass a non-NULL jboolean* you can check this value later on. If you pass NULL you do not get this information. For example, if you only intend to read from the data, then knowing whether or not it is a copy might not be interesting because you're probably just going to use JNI_ABORT when releasing the elements.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With