如何从地址位置获取直接字节缓冲区
how to get a direct byte buffer from an address location
在this opencv example中,Mat对象有一个nativeObj
字段,返回一个表示对象地址的long(即140398889556640
)。因为对象中数据的大小是已知的,所以我希望直接访问 Mat 对象的内容,返回一个字节缓冲区。
最好的方法是什么?
您可以使用 DirectByteBuffer 包装地址或使用 Unsafe。
虽然您可以这样做,但您可能不应该这样做。我会先探索所有其他选项。
// 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;
}
如果您不想使用 Unsafe
并且想要在 Java 9 中无警告地工作并且实际上可以跨 JVM 移植的东西,您可以使用 JNI NewDirectByteBuffer。这是 API 并且保证有效。
不过,您将需要编写一些 C(或 C++)代码,并随您的代码一起提供本机库。
有一个名为 "nalloc" 的小型框架,旨在帮助开发人员进行 memory/pointers 操作,它可能对您寻找直接内存地址访问的任何目的都有用。
它还使您能够以 C 风格编写 Java 程序,手动执行内存操作。
在this opencv example中,Mat对象有一个nativeObj
字段,返回一个表示对象地址的long(即140398889556640
)。因为对象中数据的大小是已知的,所以我希望直接访问 Mat 对象的内容,返回一个字节缓冲区。
最好的方法是什么?
您可以使用 DirectByteBuffer 包装地址或使用 Unsafe。
虽然您可以这样做,但您可能不应该这样做。我会先探索所有其他选项。
// 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;
}
如果您不想使用 Unsafe
并且想要在 Java 9 中无警告地工作并且实际上可以跨 JVM 移植的东西,您可以使用 JNI NewDirectByteBuffer。这是 API 并且保证有效。
不过,您将需要编写一些 C(或 C++)代码,并随您的代码一起提供本机库。
有一个名为 "nalloc" 的小型框架,旨在帮助开发人员进行 memory/pointers 操作,它可能对您寻找直接内存地址访问的任何目的都有用。
它还使您能够以 C 风格编写 Java 程序,手动执行内存操作。