Is it possible to just reference a entire bytearray in JNI but not invoking any copy ?
In native C code, I have a bytearray passing from Java, and I just want to compare some data to this bytearray so I do not want to do any memory copy. Is it possible ?
I know I could get the pointer of a bytearray in native by using GetPrimitiveArrayCritical something like that
JNIEXPORT jbyteArray JNICALL Java_nfore_android_bt_pro_nfhfp_dsp
(JNIEnv *env, jobject jobj, jbyteArray jbIn, jbyteArray jbBase){
jbyte *bufferIn;
jbyte *bufferBase;
bufferIn = (*env)->GetPrimitiveArrayCritical(env, jbIn, NULL);
LOGD("Begin of dsp()");
LOGD("In dsp() Before Comparing...");
// Compare bufferIn with bufferBase here...
LOGD("In dsp() After Comparing...");
LOGD("End of dsp()");
(*env)->ReleasePrimitiveArrayCritical(env, jbIn, bufferIn, 0);
return jbIn;
}
As you could see, because I might change the data in the jbIn, I should use GetPrimitiveArrayCritical to get its pointer and release it later.
However, if I just want to READ the bytearray jbBase, how could I get the pointer of the jbBase but not using GetPrimitiveArrayCritical ?
Any suggestion would be appreciated. Thanks a lot.
I use the following to read byte arrays...
You still need to release it as that stops the Garbage collector getting rid of it potentially while you are still using it.
GetByteArrayElements method can not guarantee that your program use reference or copy. JNI return isCopy flag for state it copied object or pinned it(pin means reference). If you dont want to copy it never, you havent to use GetArrayElements methods, because it always returns copy(JVM decides copy or not and probably copy prefered because copy eases burden of Garbage Collector). I tried it and I saw that my ram increased when sent a big array. You can also see that at below link:
IBM copy and pin (look at copy and pin subject from tree view)
As document says,GetPrimitiveArrayCritical returns the direct heap address of a Java array, disabling garbage collection until the corresponding ReleasePrimitiveArrayCritical is called. So you must use that GetPrimitiveArrayCritical, if you dont want to copy(u need that when you have a big array). If we look at your code, you can get array one by one as below(I assumed you sent int array as a jobject to JNI function):
Important Note: You cannot GetArrayLength after GetPrimitiveArrayCritical because JNI doesn't permit program to call any JNI function for same object between get critical and release methods.