在Java对象中存储本机指针的“正确”方法是什么?
我可以将指针视为Java int
,如果我碰巧知道本机指针的大小是< = 32位,或者如果我碰巧知道本地指针那么Java long
是< = 64位的大小。但有更好或更清洁的方法吗?
编辑:从JNI函数返回本机指针正是我不想要做的事情。我宁愿返回一个代表本机资源的Java对象。但是,我返回的Java对象必须有一个包含指针的字段,这会让我回到最初的问题。
或者,或者,是否有更好的方法让JNI函数返回对本机资源的引用?
答案 0 :(得分:22)
IIRC,java.util.zip
和java.nio
只使用long
。
答案 1 :(得分:3)
没有好办法。在SWT中,使用此代码:
int /*long*/ hModule = OS.GetLibraryHandle ();
并且有一个工具可以通过移动注释来转换32位和64位之间的代码。丑陋但有效。如果Sun添加了一个“NativePointer”对象或类似的东西,但事情本来会容易得多。
答案 2 :(得分:3)
java.nio.DirectByteBuffer
做你想要的。
在内部,它使用private long address
来存储指针值。 Dah!
使用JNI函数env->NewDirectByteBuffer((void*) data, sizeof(MyNativeStruct))
在C / C ++端创建DirectByteBuffer,并将其作为ByteBuffer返回到Java端。 注意:您可以在原生方面释放这些数据!它错过了标准DirectBuffer上的自动清洁器。
在Java方面,您可以通过以下方式创建DirectByteBuffer:
ByteBuffer directBuff = ByteBuffer.allocateDirect(sizeInBytes);
将其视为C的malloc(sizeInBytes)
。 注意:它具有自动清除功能,可以释放先前请求的内存。
但是有一些要考虑使用DirectByteBuffer的要点:
env->GetDirectBufferAddress(buffer)
返回的默认类型为void*
。env->NewDirectByteBuffer()
一起使用的那些。答案 3 :(得分:2)
更好的方法是将它存储在字节数组中,因为本机指针首先不是非常Java。 int
和long
最好保留用于存储数值。
答案 4 :(得分:2)
我认为这是从一些JNI代码返回的指针,我的建议是就是不要这样做 :)
理想情况下,JNI代码应该传递给资源的某种逻辑引用,而不是实际的指针?
关于你的问题,没有什么可以想到存储指针的更简洁的方法 - 如果你知道你有什么,那么根据需要使用int或long或byte []。
答案 5 :(得分:0)
你可以看看C#使用IntPtr类型处理它的方式。通过创建自己的类型来保存指针,相同的类型可以用作32位或64位,具体取决于您所使用的系统。