嵌套类的 JNI 签名?
我正在尝试在WindowsXP上使用JNI,java版本:
java版本“1.6.0_13” Java(TM) SE 运行时环境(内部版本 1.6.0_13-b03) Java HotSpot(TM) 客户端 VM(版本 11.3-b02,混合模式,共享)
当尝试获取嵌套类的 jclass 时
jclass c = env->FindClass ("A$B"); 断言(c);
第二行断言,同样的事情在 Linux 上运行正常,但 Java 版本略有不同(1.5...IIRC)。
我尝试过几种排列,例如
LA$B; AB 拉.B;
但无济于事。
任何建议将不胜感激。
马丁
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
好吧,我在 Native Android 上也有类似的经历,
env->FindClass()
找不到具有A$B
语法的嵌套类。 我移动了一些东西,它甚至找不到非嵌套类。问题是 Java->C++ JNI 调用可以找到类,但是如果你有纯 C++ 线程,使用
jvm->GetEnv / jvm->AttachCurrentThread
,该线程可以执行 JNI 操作,但由于某种原因不能执行FindClass
操作。所以我的建议是,如果您在 Android 上遇到奇怪的
FindClass
行为,请尝试将其移动到 Java 堆栈(即 Java 调用本机方法),这可能会有所帮助。 请注意,如果稍后要从另一个线程使用jclass
esp,您可能需要NewGlobalRef
。PS
A$B
是引用嵌套类的正确方法。OK, I had a similar experience on Native Android,
env->FindClass()
would not find a nested class withA$B
syntax. I moved stuff around and it wouldn't find even a non-nested class.What turned out to be the issue is that Java->C++ JNI call can find classes, but if you have pure C++ thread, with
jvm->GetEnv / jvm->AttachCurrentThread
, this thread can do JNI stuff but notFindClass
for some reason.So my suggestion is if you hit weird
FindClass
behavior on Android, try to move it to a Java stack (i.e Java calling native method), it might help. Note that you might needNewGlobalRef
for thejclass
esp if it would be used later from another thread.P.S.
A$B
is the correct way to refer to nested classes.该问题似乎已在此帖子中得到解决。
更新: Oracle 移动了论坛,新位置为 嵌套类的签名?
以下是问题的解决方法:
我的另一个提示:如果
FindClass
返回 null,不要只是assert
和猜测。 至少调用env->ExceptionDescribe()
来获取stderr
上的堆栈跟踪。 更好的是,使用env->ExceptionOccurred()
来检查是否抛出 Java 异常,就像在调用的任何其他 Java 方法上一样。Seems like the issue was resolved in this thread.
Update: Oracle moved the the forums, the new location is Signature for nested class?
Here's how the issue was resolved:
Another hint from me: In case
FindClass
returns null don't justassert
and guess. At the very least callenv->ExceptionDescribe()
to get a stacktrace onstderr
. Better still, useenv->ExceptionOccurred()
to check for the Java exception being thrown, just like you would on any other Java method you call.