1

我想围绕本机 c++ 对象创建一个 java 对象包装器。我通过将指向 c++ 对象的指针放在直接的 ByteBuffer 中来做到这一点,如下所示:

java端:

public class World {
  private final ByteBuffer pointer;
  public World() {
    pointer = init();
  }

  private native ByteBuffer init();
  public native void destroy();
}

本机方面:

extern "C" jobject Java_blabla_World_init(JNIEnv *e, jobject self) {
  return env->NewDirectByteBuffer(new World, sizeof(World));
}

安全吗?意思是,java会对我的指针做一些有趣的事情,比如重新定位它或垃圾收集它?

其次,如果我事先不知道 World 的大小(它是前向声明的),可以只给出0缓冲区大小吗?(当然,前提是我不尝试从缓冲区中读取)

4

2 回答 2

1

JVM 可以自由管理 ByteBuffer 对象,但它始终包含相同的地址和容量。它不会对 ByteBuffer 指向的内存做任何事情,除非你在它上面调用 ByteBuffer 方法并且它永远不会移动它。

但是由于您不打算调用 ByteBuffer 方法,因此 ByteBuffer 和 jlong​​ 是等价的。在我看来,使用 jlong​​ 会更清楚,即使您必须在 JNI 函数中进行转换。毕竟,在 Java 端,您正在创建和存储句柄,而在 JNI 端,您将句柄视为指针。演员表清楚地说明了这一点。

于 2013-05-10T13:41:56.527 回答
0

意思是,java会对我的指针做一些有趣的事情,比如重新定位它或垃圾收集它?

你的指针只是一个 32 位数字。如果你不改变它,JVM 就不会。

JVM“知道”引用在哪里的唯一原因是因为它们作为类的字段出现。这不是一个字段,也不是存储在引用中。

其次,如果我事先不知道 World 的大小(它是前向声明的),是否可以只给出 0 作为缓冲区大小?

不,一个 ByteBuffer 是一个固定的大小,你不能超过它。当你知道它应该有多大时,我会设置 ByteBuffer。

我不清楚您要做什么,但我怀疑有更好的方法可以做到这一点。

于 2013-05-10T06:41:07.887 回答