JNI:如何获取方法签名以进行调试

Pav*_*l P 5 c++ java java-native-interface android-ndk

  1. 我可以枚举java中的所有本机方法,那些必须使用JNI在c/c++中实现的方法吗?
  2. 我可以按名称枚举本机方法(可能有多个同名重载)?
  3. 如何检索方法签名以便能够生成 JNI 使用的方法签名?

有没有办法检查所有本机 jni 方法是否已正确绑定,而不是尝试调用它们并获取 java.lang.UnsatisfiedLinkError 异常。有时方法签名会在任何一方发生变化而没有正确更新 java 或 c++ 端,我想添加一些调试代码来检测这些问题并处理它们(也许通过生成正确的方法签名并将其打印到日志中,以便我可以轻松修复代码)。

我更喜欢 JNI 解决方案,但如果可以在 java 端的帮助下完成某些操作,那么也可以。如果我使用 registerNatives 并注册未在 java 中声明的方法,则会失败并将其打印到 logcat:

E/dalvikvm( 1445): ERROR: couldn't find native method
E/dalvikvm( 1445): Requested: Lcom/bla/bla/bla/Test;.nativeTestXX:()Z
Run Code Online (Sandbox Code Playgroud)

但我想捕获这个错误并自己处理。有可能做到吗?

编辑: 在我的 JNI 代码中,我有一个静态的 nativeInit (如Android JNI Tips中所建议的),它注册所有本机方法。在同一函数中,我想验证所有本机方法是否已正确绑定。也就是说,我不需要等到调用某些未初始化的方法并且应用程序存在。我遇到的问题是:有很多 jni 代码是由不同的人在不同的时间编写的,并且某些方法根本不正确,但它们仅在某些模糊的条件下使用。我认为对我来说最好的方法是检查所有本机方法是否都绑定到某个 C++ 函数。另一个问题是,部分 JNI 代码通过导出所有这些 Long_java_name 来使用绑定,其中任何一方的方法签名更改都无法检测到。

fad*_*den 0

没有调用来检查“未绑定”本机方法。使用 RegisterNatives 执行显式注册可确保您注册的所有方法在 Java 源中都有匹配的声明,但无法检查没有实现的本机声明方法(除了调用它并捕获异常)。

在调用具有本机实现的方法时,如果尚未注册任何内容,则 Dalvik 将搜索各种共享库以查找匹配项。听起来您想要的是一种强制执行此搜索并检查结果而不实际调用该方法的方法。哪有这回事。

有多种方法可以静态或在运行时生成本机声明的方法列表,但您还需要一种方法来确定实现是否可用。从长远来看,进行单元测试来执行代码会更好。