是什么导致 JNI 错误“使用已删除的本地引用”?

don*_*ner 3 c java java-native-interface android jvm

我有一个 Android 应用程序,其中在应用程序启动时调用以下 C 方法(在 中Activity.onCreate)。

extern "C"
JNIEXPORT jstring JNICALL
Java_com_google_oboe_test_oboetest_MainActivity_stringFromJNI(
    JNIEnv *env,
    jobject instance) {

    jclass sysclazz = env->FindClass("java/lang/System");
    jmethodID getPropertyMethod = env->GetStaticMethodID(sysclazz, "getProperty", "(Ljava/lang/String;)Ljava/lang/String;");
    jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");
    return result;
}
Run Code Online (Sandbox Code Playgroud)

当调用此方法时,应用程序崩溃并出现错误:

JNI 在应用程序中检测到错误:使用已删除的本地引用 0xd280e8d5

步骤调试显示这一行导致崩溃:

jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, "os.name");
Run Code Online (Sandbox Code Playgroud)

是什么导致了这个错误?以及如何System.getProperty("os.name")使用 JNI调用而不会出现此错误?

don*_*ner 9

问题是env->CallStaticObjectMethod期望 ajstring作为它的第三个参数,而是提供了一个字符串文字。

创建jstring第一个

jstring arg = env->NewStringUTF("os.name");
jstring result = (jstring) env->CallStaticObjectMethod(sysclazz, getPropertyMethod, arg);
Run Code Online (Sandbox Code Playgroud)

解决了这个问题。

  • @shizhen:没有必要,因为`stringFromJNI` 会返回给java,java 会自动清除已经创建的本地引用。 (3认同)