如何为字段或方法获取JNI样式的签名字符串?

时间:2014-11-18 22:38:26

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

我正在尝试检查Java类并自动检索其所有方法和字段,我可以通过Android上的JNI调用它们。但是,我无法弄清楚如何以编程方式实际获取文本签名字符串;我知道如何从命令行通过javap -s获取它,但我想从我的程序中获取它。

我能找到最接近的是使用clazz.getMethods()来获取单个方法,然后使用Method.toGenericString()来获取人类可读的字符串,但该字符串的格式与Java代码签名类似(例如{{ 1}})当我真的只想要JNI样式的签名(例如public int someMethod(int foo, java.lang.String bar))时,因为我需要该字符串从JNI调用(ILjava/lang/String;)I并且我已经有一个非常好的解析器来解析那些JNI首先签名。

我可以手动维护我真正关心从JNI访问的类的绑定,但我更愿意尽可能自动地处理所有内容;毕竟,代码越少越好。

我确实找到了为此提供辅助方法的ASM,但它似乎是一个字节码生成框架,我不确定它是否与Android兼容。

或者,换句话说,给定以下类:

getMethodID()

我想创建一个名为class SomeClass { String foo(int bar) { return "This is foo " + bar; } } 的类,可以执行以下操作:

ClassInspector

这就是说我希望能够从Java中获取ClassInspector ci = new ClassInspector(SomeClass.class); int n = ci.getMethodCount(); // returns 1 String name = ci.getMethodName(0); // returns "foo" String sig = ci.getMethodSignature(0); // returns "(I)Ljava/lang/string;" 的输出,以便我可以从本机端调用Java方法。

1 个答案:

答案 0 :(得分:1)

我遇到了同样的问题而我找不到“干净”的解决方案。

最后,我决定使用相同的方法创建一个虚拟类,但声明为native。 然后我使用javah创建头文件,我从该头文件中获取签名。

我知道它看起来不太好......但我找不到更好的选择(除了根据Method属性“手动”创建它)。