为什么调用CallVoidMethod会将无效的jobject与JNI一起使用

时间:2016-04-10 09:00:02

标签: android java-native-interface

当我尝试这样做时,我是JNI的初学者:

JNIEXPORT jstring JNICALL Java_com_example_kalexjune_digitalimage_MainActivity_getBalanceMatrix(JNIEnv *env,
                                                                      jobject instance) {
    // TODO
    jclass jcs;
    jmethodID mid;
    jstring arg;
    jobject mobj;
    mobj = (*env)->NewGlobalRef(env,instance);
    jcs = (*env)->GetObjectClass(env,instance);
    mid = (*env)->GetMethodID(env,jcs,"setMatrix","(Ljava/lang/String;)V");
    if(mid!=0){
        (*env)->CallVoidMethod(env,mobj,mid,arg);

        const char * ss = (*env)->GetStringUTFChars(env,arg,0);
        printf("from native: %s\n",ss);
    }

    return (*env)->NewStringUTF(env, "hello,i'm from native");
}

已记录:

JNI DETECTED ERROR IN APPLICATION: use of invalid jobject 0x7f49b9dd2240
...
libart.so (art::CheckJNI::CallMethodV(char const*, _JNIEnv*, _jobject*, _jclass*,...
lib64/libart.so (art::CheckJNI::CallVoidMethod(_JNIEnv*, _jobject*, _jmethodID*, ...)+151)    
digitalimage-1/lib/x86_64/libdigital-jni.so (Java_com_example_kalexjune_digitalimage_MainActivity_getBalanceMatrix+174)

我的问题是:

它表示命名实例无效的参数?

我该怎么做才能解决我的问题?

(忘了我可怜的英语.. :)

1 个答案:

答案 0 :(得分:1)

您似乎有一个未初始化的jstring对象,很容易导致JNI错误。 JNI函数不能将jstring用作[out]参数。实际上,任何Java方法的java.lang.String参数都是“不可变的”。你可以把你的作品重写为

mid = (*env)->GetMethodID(env,jcs,"setMatrix","()Ljava/lang/String;");
 
arg = (*env)->CallObjectMethod(env, mobj, mid);
const char *ss = (*env)->GetStringUTFChars(env, arg, 0);

(当然这也需要在Java方面进行更改)。

请注意,您的代码段中还有其他问题:您必须调用ReleaseStringUTFChars(),而printf输出将无效:您应该使用__android_log_print()代替。