decodeIndirectRef

时间:2016-04-25 11:27:16

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

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

我在班级标题中,作为私人成员:

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表并崩溃。

1 个答案:

答案 0 :(得分:2)

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

  

decodeIndirectRef

中的间接引用0x416f68a0无效

这意味着你给出了错误的论点,第二个&#34; mavlinkMsgMethod&#34;。 根据我的经验,如果您将&#34; mavlinkMsgMethod&#34; 更改为&#34; 5&#34; 等数字, 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);