How to read bytearray in JNI?

Is it possible to simply reference the entire bytearray in JNI, but not reference any copy?

In native C code, I have a bytearray transitioning from Java, and I just want to compare some data with this bytearray, so I don't want to make any copy of the memory. Is it possible?

I know that I could get a pointer to a bytearray in native using GetPrimitiveArrayCritical, something like this

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 can see, because I can change the data in jbIn, I have to use GetPrimitiveArrayCritical to get its pointer and release it later.

However, if I just want to READ bytearray jbBase, how can I get a pointer to jbBase but not using GetPrimitiveArrayCritical?

Any suggestion will be appreciated. Thank you very much.

+4
source share
2 answers

I use the following to read byte arrays ...

 jbyte *b = (jbyte *)env->GetByteArrayElements(jbBase, NULL); // read bytes in *b here ... // release it env->ReleaseByteArrayElements(jbBase, b, 0 ); 

You still need to free it, as this will stop the garbage collector from disposing of it, possibly while you use it.

+9
source

The GetByteArrayElements method cannot guarantee that your program uses a link or copy. JNI return isCopy flag in order to copy an object or copy it (link means link). If you never want to copy it, you do not need to use GetArrayElements methods because it always returns a copy (the JVM decides to copy or not and probably prefers to copy because the copy eases the burden of the Garbage Collector). I tried this, and I saw that my ram increased when I sent a large array. You can also see the link below:

IBM copy and pin (look at the topic of copying and output from the tree)

As the document says, GetPrimitiveArrayCritical returns the address of the direct heap of the Java array, disabling garbage collection before calling the corresponding ReleasePrimitiveArrayCritical. Therefore, you should use this GetPrimitiveArrayCritical if you do not want to copy (you need it when you have a large array). If we look at your code, you can get the array one by one, as shown below (I assumed that you sent an int array as an object for the JNI function):

 length = (*env)->GetArrayLength(jbIn); bufferIn = (*env)->GetPrimitiveArrayCritical(env, jbIn, NULL); for(int i=0; i<length; i++) printf("Value of jbIn[%d]: %d", i, bufferIn[i]); (*env)->ReleasePrimitiveArrayCritical(env, jbIn, bufferIn, 0); 

Important note: you cannot GetArrayLength after GetPrimitiveArrayCritical, because JNI does not allow the program to call any JNI function for the same object between critical and deallocation methods.

+6
source

All Articles