GetByteArrayElements和ReleaseByteArrayElements

GetByteArrayElements的官方解释:

Returns the body of the primitive array. The result is valid until
the corresponding Release<Type>ArrayElements function is
called.Since the returned array may be a copy of the original
array, changes made to the returned array will not necessarily
be reflected in the original array until a corresponding
Release<Type>ArrayElementsis called.
IfisCopyis notNULL, then*isCopyis set toJNI_TRUEif a copy
is made; if no copy is made, it is set toJNI_FALSE.

在使用

GetByteArrayElements
时:
byteBuffer = env->GetByteArrayElements(buffer, JNI_FALSE);
/*  当第二个参数为0时,个人理解此接口只是一个指针转换。
但是,如果你需要确保byteBuffer 指针的数据和buffer同步(参见红色说明),
必须调用: env->ReleaseByteArrayElements(buffer, byteBuffer, 0);
*/
在使用
ReleaseByteArrayElements
时:

env->ReleaseByteArrayElements(buffer, byteBuffer, JNI_FALSE);
/*小心最后一个参数,如果为0是会释放 m 所指向的内存的. 如果M刚好指向一个栈上的数组的话,
这样可能在Release 版本中造成内存方面的随机错误.可以用JNI_COMMIT来避免.
*/

解决方法摘自:http://blog.csdn.net/rainlight/article/details/818964

其实现代码也许如下

+void
+KaffeJNI_ReleaseByteArrayElements(JNIEnv* env UNUSED, jbyteArray arr, jbyte* elems, jint mode)
+{
+ BEGIN_EXCEPTION_HANDLING_VOID();
+
+ if (elems != unhand_array((HArrayOfByte*)arr)->body) {
+ switch (mode) {
+ case JNI_COMMIT:
+ memcpy(unhand_array((HArrayOfByte*)arr)->body, elems, obj_length((HArrayOfByte*)arr) * sizeof(jbyte));
+ break;
+ case 0:
+ memcpy(unhand_array((HArrayOfByte*)arr)->body, elems, obj_length((HArrayOfByte*)arr) * sizeof(jbyte));
+ KFREE(elems);
+ break;
+ case JNI_ABORT:
+ KFREE(elems);
+ break;
+ }
+ }
+ END_EXCEPTION_HANDLING();
+}


JNI_COMMIT forces the native array to be copied back to the original array in the Java virtual machine.JNI_ABORTfrees the memory allocated for the native array without copying back the new contents



你可能感兴趣的:(jni)