1

我已经阅读了一些关于 JNI 中本地和全局引用的参考资料。但是我找不到明确的答案,作为参数传递给 JNI 函数的 Java 对象是本地引用还是全局引用。我认为它应该是全球性的,但是有一个问题:

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

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

4

2 回答 2

5
  1. 这是本地参考。“对象作为本地引用传递给本地方法”

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

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

于 2012-04-24T04:06:57.897 回答
0

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

编辑:以上是经过编辑的版本,我希望能更满足@EJP。同样的信息,只是更清晰。他确实有一点,对于几乎所有情况,JNI 规范都是最重要的,即使它在这种情况下没有任何区别 :-)

于 2012-04-23T21:12:23.993 回答