【问题标题】:JNI: How to get method signature for debugging purposesJNI:如何获取用于调试目的的方法签名
【发布时间】:2012-11-01 07:18:19
【问题描述】:
  1. 我可以枚举Java中的所有本机方法吗? 使用 JNI 在 c/c++ 中实现?
  2. 我可以通过以下方式枚举本机方法吗? 名称(可能有多个具有相同名称的重载)?
  3. 如何检索方法签名才能生成方法 JNI 使用的签名?

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

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

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

但我想发现这个错误并自己处理。有可能吗?

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

【问题讨论】:

  • 这叫做单元测试。你编写了一个单元测试来调用每个应该存在的本地方法。您不要编写尝试自行调试的代码。
  • java.lang.reflect.Modifier 可能是你的朋友,但@EJP 是非常正确的。也许您正在尝试编写自动化单元测试,但无论如何它都是错误的路径。单元测试单元测试是一个可怕的想法。
  • 我不是在写自动化单元测试。这只是为了验证在 ja​​va 端声明的所有本机方法实际上都绑定到某些函数,而不是等待在 rune-time 抛出这些错误。在原始问题中查看我的编辑

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


【解决方案1】:

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

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

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

【讨论】:

    猜你喜欢
    • 2023-03-07
    • 2012-07-10
    • 2020-04-21
    • 1970-01-01
    • 2011-07-03
    • 2014-07-11
    • 2013-07-07
    • 1970-01-01
    • 2011-02-08
    相关资源
    最近更新 更多