你的Java版本的SimpleClass应该做两件事。首先,保留一个私有 long 值,该值存储指向支持本机对象的 C++ 指针的值(您可能必须使用 BigInteger,具体取决于本机指针的大小 - 无符号 long long?)。第二,使公共方法(例如)成为本机。setIntVal
public class SimpleClass {
private long nativePtr;
public SimpleClass() {
nativePtr = initNativeSimpleClass();
}
public void destroy() {
destroyNativeSimpleClass();
nativePtr = 0L;
}
protected void finalize() throws Throwable {
destroyNativeSimpleClass();
nativePtr = 0L;
}
public native int getIntVal();
public native void setIntVal(int val);
private native long initNativeSimpleClass();
private native void destroyNativeSimpleClass();
}
然后在 JNI 代码中实现这些本机方法。该方法将新建一个支持C++ 实例。然后,该方法将删除该实例。访问器方法将使用 的值,将其转换为实际指针,并在本机支持实例上执行相应的操作。initNativeSimpleClass()
SimpleClass
destroyNativeSimpleClass()
nativePtr
这个成语带来了泄漏内存的真正风险,因为该类的用户在完成实例时必须调用 destroy。否则,后备本机实例可能无法正确销毁。正如我在示例中所示,您可以覆盖以调用本机破坏器函数,但是有关如何依赖finize的所有警告仍然适用。通过在销毁时将值设置为 0,可以避免在多次调用销毁时出现 seg 错误(C++删除 NULL 是安全的)。finalize
nativePtr