JNI参数是本地或全局引用

时间:2012-04-23 21:04:43

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

我在JNI中读过几篇关于本地和全局引用的参考资料。但我无法找到一个明确的答案,将作为参数传递给JNI函数的Java对象是本地引用还是全局引用。我认为它应该是全球性的,但有一个问题:

首先,我获取Java对象指针并保存它。然后本机回调函数调用该对象的方法。回调函数是从一个单独的线程调用的。该线程是使用AttachCurrentThread()创建的,因此JVM知道它。 JNIEnv *变量也是有效的,并且该对象不是垃圾卡,但是我收到警告然后崩溃。

  

JNI警告:0x4108edb8不是有效的JNI引用   Lcom / my / company / MyClass; .load:(Ljava / lang / String;)V(GetObjectClass)

2 个答案:

答案 0 :(得分:4)

  1. 这是一个本地参考。 "Objects are passed to native methods as local references"

  2. JNIEnv *指针在JNI方法调用边界上无效,更不用说线程边界了。

  3. 在您的情况下,您必须将本地引用转换为全局引用以供回调方法使用。

答案 1 :(得分:0)

理论上,如果没有从Java代码中调用函数,你可以得到一个全局引用(我有时直接从其他JNI方法调用我的JNI方法而不要求JVM这样做)但是你应该总是假设它们是本地的并且对待它他们就是这样。如果要存储它们供以后使用,则应创建一个新的gobal引用。 事实上,即使你可以获得全球参考,你应该如何对待它们也没有区别。在任何情况下你都不必删除它们,即使你碰巧得到全局引用(我认为上面描述的方式是唯一的方法),存储它而不首先对它进行新的引用是错误的。如果有人给你删除参考,它将变为无效。

编辑:上面是一个经过编辑的版本,希望能更多地满足@EJP。同样的消息,更清楚。而且他确实有一点,几乎在所有情况下,JNI规范都很重要,即使它在这种情况下没有任何区别: - )