Boh*_* Lu 5 java-native-interface bytearray pass-by-reference
是否可以在JNI中引用整个bytearray但不调用任何副本?
在本机C代码中,我有一个从Java传递的bytearray,我只是想将一些数据与这个bytearray进行比较,所以我不想做任何内存复制.可能吗 ?
我知道我可以通过使用GetPrimitiveArrayCritical来获取本地的bytearray指针
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;
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,因为我可能会更改jbIn中的数据,所以我应该使用GetPrimitiveArrayCritical获取其指针并稍后释放它.
但是,如果我只想读取bytearray jbBase,我怎么能得到jbBase的指针但不使用GetPrimitiveArrayCritical?
任何建议将不胜感激.非常感谢.
Jim*_*ris 10
我使用以下内容读取字节数组...
jbyte *b = (jbyte *)env->GetByteArrayElements(jbBase, NULL);
// read bytes in *b here
...
// release it
env->ReleaseByteArrayElements(jbBase, b, 0 );
Run Code Online (Sandbox Code Playgroud)
你仍然需要释放它,因为当你还在使用它时,它会阻止垃圾收集器摆脱它.
GetByteArrayElements方法不能保证您的程序使用引用或复制.JNI返回isCopy标志,表示它复制了对象或固定它(pin表示引用).如果你不想永远复制它,你不必使用GetArrayElements方法,因为它总是返回副本(JVM决定复制与否,可能复制首选,因为复制减轻了垃圾收集器的负担).我试过了,看到我的ram在发送一个大阵列时增加了.您还可以在以下链接中看到:
IBM副本和引脚 (从树视图查看副本和引脚主题)
正如文档所述,GetPrimitiveArrayCritical返回Java数组的直接堆地址,禁用垃圾收集,直到调用相应的ReleasePrimitiveArrayCritical.所以你必须使用GetPrimitiveArrayCritical,如果你不想复制(当你拥有一个大数组时需要它).如果我们查看您的代码,您可以按如下所示逐个获取数组(我假设您将int数组作为jobject发送到JNI函数):
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);
Run Code Online (Sandbox Code Playgroud)
重要说明:GetPrimitiveArrayCritical之后不能使用GetArrayLength,因为JNI不允许程序在get critical和release方法之间调用同一对象的任何JNI函数.
| 归档时间: |
|
| 查看次数: |
13425 次 |
| 最近记录: |