java.nio.DirectByteBuffer
does what you want.
Internally it uses a private long address
to store pointer value. Dah !
Use JNI function env->NewDirectByteBuffer((void*) data, sizeof(MyNativeStruct))
to create a DirectByteBuffer on C/C++ side and return it to Java side as a ByteBuffer. Note: It's your job to free this data at native side! It miss the automatic Cleaner available on standard DirectBuffer.
At Java side, you can create a DirectByteBuffer this way :
ByteBuffer directBuff = ByteBuffer.allocateDirect(sizeInBytes);
Think it as sort of C's malloc(sizeInBytes)
. Note: It has as automatic Cleaner, which deallocates the memory previously requested.
But there are some points to consider about using DirectByteBuffer:
- It can be Garbage Collected (GC) if you miss your direct ByteBuffer reference.
- You can read/write values to pointed structure, but beware with both offset and data size. Compiler may add extra spaces for padding and break your assumed internal offsets in structure. Structure with pointers (stride is 4 or 8 bytes ?) also puzzle your data.
- Direct ByteBuffers are very easy to pass as a parameter for native methods, as well to get it back as return.
- You must cast to correct pointer type at JNI side. Default type returned by
env->GetDirectBufferAddress(buffer)
is void*
.
- You are unable to change pointer value once created.
- Its your job to free memory previously allocated for buffers at native side. That ones you used with
env->NewDirectByteBuffer()
.