【发布时间】: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