decodeIndirectRef 中的间接引用 0x416f68a0 无效

Invalid indirect reference 0x416f68a0 in decodeIndirectRef

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

我的 class header,作为私人会员:

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

然后在 class 的源代码中:

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时出现上述错误失败。

Invalid indirect reference 0x416f68a0 in decodeIndirectRef

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

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

编辑:虽然我认为 Bangyno 的回答是正确的,但我最终尽可能快地解决问题的方法是将 Java 将从 C++ 调用的方法声明为静态.这样我就不必调用构造函数,而且一切都变得更有意义了。因为我调用的 Java class 是一个 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 table 并崩溃。

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

Invalid indirect reference 0x416f68a0 in decodeIndirectRef

说明你给错了参数,第二个"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);