如何从地址位置获取直接字节缓冲区

时间:2018-10-03 09:55:07

标签: java opencv bytebuffer unsafe

this opencv example中,Mat对象具有一个nativeObj字段,返回代表该对象地址的long(即140398889556640)。因为已知对象内数据的大小,所以我希望直接访问Mat对象的内容,并返回一个字节缓冲区。

这样做的最佳方法是什么?

3 个答案:

答案 0 :(得分:3)

您可以使用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;
}

答案 1 :(得分:1)

如果您不想使用Unsafe,并且想要在Java 9中没有警告就可以正常工作并且可以跨JVM移植的东西,则可以使用JNI NewDirectByteBuffer。这是API,可以保证正常工作。

但是,您将需要编写一些C(或C ++)代码,并随代码一起提供本机库。

答案 2 :(得分:0)

有一个名为“ nalloc”的微型框架,旨在帮助开发人员进行内存/指针操作,无论您要寻找直接内存地址访问的任何目的,它都可能会很有用。

它还使您能够以C样式编写Java程序,并手动执行内存操作。

签出:https://github.com/alaisi/nalloc