【问题标题】:Invalid indirect reference 0x416f68a0 in decodeIndirectRefdecodeIndirectRef 中的间接引用 0x416f68a0 无效
【发布时间】:2016-04-25 11:27:15
【问题描述】:

我已经看到很多关于完全相同错误的问题,但似乎没有一个人试图做这个简单的事情并且仍然失败。

我的班级标题中有私人成员:

static JNIEnv* env;
static jclass copterServiceClass;
static jmethodID mavlinkMsgMethod;

然后在该类的源代码中:

JNIEnv* JU_Calls::env = 0;
jclass JU_Calls::copterServiceClass = 0;
jmethodID JU_Calls::mavlinkMsgMethod = 0;

bool JU_Calls::setupJNICalls() {

    if (cached_jvm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
        __android_log_print(ANDROID_LOG_ERROR, TAG, "Unable to get Java Env from cached JavaVM");
        return -1;
    }

    jclass dataClass = env->FindClass("eu/deye/copterdroidair/copterdroidair/Services/CopterService");
    copterServiceClass = (jclass) env->NewGlobalRef(dataClass);
    mavlinkMsgMethod = env->GetMethodID(copterServiceClass, "MavlinkMsg", "(Ljava/lang/String;)V");

    jobject javaObjectRef = env->NewObject(copterServiceClass, mavlinkMsgMethod);
    jstring msg = env->NewStringUTF("aaaa");
    env->CallVoidMethod(javaObjectRef, mavlinkMsgMethod, msg);

    return true;
}

注意:cached_jvm 分配给 JNI_OnLoad

执行NewObject时失败并出现上述错误。

decodeIndirectRef 中的间接引用 0x416f68a0 无效

我尝试将 NULL 作为消息传递给 CallVoidMethod,正如其他人的问题所看到的那样,但由于它是合乎逻辑的,问题是以前的,所以没用。

希望您能一如既往地帮助我,伟大的 SO 大师 ;)

编辑:虽然我认为 Bangyno 的答案是正确的,但我最终尽可能快地解决问题的方法是将 C++ 调用的 Java 方法声明为静态的。这样我就不必调用构造函数了,一切都变得更有意义了。因为我调用的 Java 类是一个 Android 服务,所以调用构造函数肯定是错误的。

除了声明Java方法static,得到的C++代码结果如下:

jclass copterServiceClass = env->FindClass("eu/deye/copterdroidair/copterdroidair/Services/CopterService");
jmethodID mavlinkMsgMethod = env->GetStaticMethodID(copterServiceClass, "MavlinkMsg", "(ILjava/lang/String;)V");
jstring msg = env->NewStringUTF(str);
env->CallStaticVoidMethod(copterServiceClass, mavlinkMsgMethod, severity, msg);
env->DeleteLocalRef(msg);

不要忘记最后一行非常重要,否则它会填满你的 JNI 表并崩溃。

【问题讨论】:

  • setupJNICalls 是从哪里调用的?此外,您几乎没有错误检查。您应该在每次 JNI 调用后检查返回值和/或执行状态。
  • 哦,NewObject 的第二个参数显然应该是CopterService 的构造函数之一的jmethodID
  • 这是有道理的,但我关注的是mobileway.net/2015/03/20/…,而那个方法似乎不是构造函数......你怎么看?谢谢!
  • 您必须询问编写教程的人。我个人认为它看起来不正确,我会确保关注the official documentation
  • 值 0x416f68a0 看起来像一个指针,而不是间接引用。如果在预期对象时传递了方法 ID,则可能会发生这种情况,但我在您发布的代码中看不到任何这样做的内容。

标签: android android-ndk java-native-interface


【解决方案1】:

这里我要讨论的是错误信息:

decodeIndirectRef 中的间接引用 0x416f68a0 无效

这意味着你给出了错误的参数,第二个“mavlinkMsgMethod”。 根据我的经验,如果您将 "mavlinkMsgMethod" 更改为诸如 "5" 之类的数字,则 0x416f68a0 将更改为 0x5。

使用newObject的正确方法是调用构造函数。它应该看起来像这样,只是一个示例:

jclass dataClass = env->FindClass("eu/deye/copterdroidair/copterdroidair/Services/CopterService");
mavlinkMsgMethod = env->GetMethodID(copterServiceClass, "<init>", "(Ljava/lang/String;)V");
jstring str = env->NewStringUTF("testing");    
jobject javaObjectRef = env->NewObject(copterServiceClass, mavlinkMsgMethod, str);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-06-18
    • 1970-01-01
    • 2011-10-11
    • 1970-01-01
    • 2013-07-11
    • 1970-01-01
    • 2015-07-04
    相关资源
    最近更新 更多