方法签名和实际调用之间的不匹配

Joã*_*ela 6 java-native-interface android

在android上使用java原生界面时,我犯了两个愚蠢的错误,花了我很多时间.

有这个方法id:

jmethodID myMethod_methodID = env->GetMethodID(hello_Cls, "myMethod", "(ILjava/lang/String;Ljava/lang/String;I)Z");
Run Code Online (Sandbox Code Playgroud)

我的第一个错误是使用它

env->CallVoidMethod
Run Code Online (Sandbox Code Playgroud)

而我的第二个错误是这样称呼它

jboolean rv = jenv->CallBooleanMethod(hello_obj, myMethod_methodID, myfirst_jstring, mysecond_jstring, 1);
Run Code Online (Sandbox Code Playgroud)

这显然错过了和jint之间的争论.myMethod_methodIDmyfirst_jstring

我花了很长时间来跟踪这些错误,因为logcat中没有相关的输出,唯一的行为是没有做任何事情(它甚至没有崩溃).

所以,问题是:如何为这类错误获得更有意义的错误?

Ale*_*dam 4

此页面可能有用:http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html,特别是:

JNI 很少进行错误检查。对对象字段调用 SetFieldInt 将成功。目标是最大限度地减少开销,假设如果您用本机代码编写它,那么您可能是出于性能原因而这样做的。

某些 VM 支持使用“-Xcheck:jni”标志进行扩展检查。如果设置了该标志,VM 会将不同的函数表放入 JavaVM 和 JNIEnv 指针中。这些函数在调用标准实现之前会执行一系列扩展的检查。

一些可以验证的事情:

  • 检查不允许的空指针。
  • 验证参数类型的正确性(jclass 是类对象,jfieldID 指向字段数据,jstring 是 java.lang.String)。
  • 字段类型正确性,例如不要将 HashMap 存储在字符串字段中。
  • 检查挂起异常不合法的调用是否有挂起异常。
  • 检查关键 get/release 调用之间是否调用了不适当的函数。
  • 检查 JNIEnv 结构是否未在线程之间共享。
  • 确保本地引用不会在其允许的使用寿命之外使用。
  • UTF-8 字符串包含有效的“修改的 UTF-8”数据。

不检查方法和字段的可访问性(即公共与私有)。

点击链接:http://www.netmite.com/android/mydroid/dalvik/docs/embedded-vm-control.html

您可以按如下方式设置 adb:

adb shell setprop dalvik.vm.checkjni true
adb shell setprop dalvik.vm.execution-mode int:debug
Run Code Online (Sandbox Code Playgroud)