在JNI中分配的数组问题

3

我编写了一个在Android JNI中分配Java数组的函数。然而,如果连续从Java中调用此函数,将会出现错误[*致命信号11(SIGSEGV)]。

C++

static jbyteArray buffer = NULL;
static int cbuflen = 0;
jbyteArray Java_com_sample_buffer_Buffer_updateBuffer(JNIEnv* env, jobject thiz, jlong handle, jint buflen)
{
    if(buflen > cbuflen){
        if(buffer != NULL) env->DeleteLocalRef(buffer);
        buffer = env->NewByteArray(buflen);
        cbuflen = buflen;
    }
    return buffer;
}

Java

byte[] buf = conv.updateBuffer(buflen);

我不应该使用这种方式吗?还是有其他的方法?

“Called continuously” 是什么意思?你是从多个线程中调用它吗? - Graham Borland
为什么要用JNI来写这个?在Java中更有效率,并且Java中已经有类可以帮你完成这个任务,例如ByteArrayOutputStream。 - user207421
1个回答

4

如果您想在JNI调用之间保留jobject(例如jbyteArray),则需要将其转换为GlobalRef:

jbyteArray temp_buffer = env->NewByteArray(buflen);
buffer = (jbyteArray)env->NewGlobalRef(temp_buffer);

只有在需要释放内存时才记得删除对象:

env->DeleteGlobalRef(buffer);

请参考http://developer.android.com/guide/practices/jni.html#local_and_global_references。另外,如果您启用了CheckJNI(在该页面中有描述),当Dalvik看到这样的事情时,它会非常大声地抱怨。 - fadden
@Mārtiņš Možeiko,在你的代码中,temp_buffer是自动释放的吗?还是应该调用env->DeleteLocalRef(temp_buffer)来释放它? - Bliss
当您从JNI方法返回时,本地引用会自动释放,因此不需要手动处理。但是如果您想要显式地管理本地引用的生命周期,可以使用DeleteLocalRef或使用PopLocalFrame批量处理。 - Mārtiņš Možeiko

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接