问题
In this opencv example, the Mat object has a nativeObj
field, returning a long that represents the address of the object (i.e 140398889556640
). Because the size of the data within the object is known, I wish to access the contents of the Mat object directly, returning a byte buffer.
What is the best way to do so?
回答1:
You can wrap the address with a DirectByteBuffer or use Unsafe.
While you can do this, you probably shouldn't. I would explore all other options first.
// Warning: only do this if there is no better option
public static void main(String[] args) {
ByteBuffer bb = ByteBuffer.allocateDirect(128);
long addr = ((DirectBuffer) bb).address();
ByteBuffer bb2 = wrapAddress(addr, bb.capacity());
bb.putLong(0, 0x12345678);
System.out.println(Long.toHexString(bb2.getLong(0)));
}
static final Field address, capacity;
static {
try {
address = Buffer.class.getDeclaredField("address");
address.setAccessible(true);
capacity = Buffer.class.getDeclaredField("capacity");
capacity.setAccessible(true);
} catch (NoSuchFieldException e) {
throw new AssertionError(e);
}
}
public static ByteBuffer wrapAddress(long addr, int length) {
ByteBuffer bb = ByteBuffer.allocateDirect(0).order(ByteOrder.nativeOrder());
try {
address.setLong(bb, addr);
capacity.setInt(bb, length);
bb.clear();
} catch (IllegalAccessException e) {
throw new AssertionError(e);
}
return bb;
}
回答2:
If you don't want to use Unsafe
and want something that works without warnings in Java 9 and is actually portable across JVMs you can use JNIs NewDirectByteBuffer. This is API and guaranteed to work.
You will need to write some C (or C++) code however and ship a native library with your code.
回答3:
There is a tiny framework called "nalloc" which is designed to help developer with memory/pointers manipulations, it could be useful for whatever purposes you are looking for direct memory address accessing.
Also it brings you ability to write your Java program in a C-style, doing memory stuff manually.
Check it out: https://github.com/alaisi/nalloc
来源:https://stackoverflow.com/questions/52624395/how-to-get-a-direct-byte-buffer-from-an-address-location