【问题标题】:how to get a direct byte buffer from an address location如何从地址位置获取直接字节缓冲区
【发布时间】:2018-10-03 09:55:07
【问题描述】:

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

最好的方法是什么?

【问题讨论】:

  • 在不知道可以安全访问多少的情况下无法访问内存。
  • 数据大小未知,就是mat.total() * mat.channels()
  • 而不是nativeObj(它指向cv::Mat 实例,而不是像素),看起来你想要dataAddr。查看源代码,它为您提供了值cv::Mat::data,它指向像素数据。请记住,您还必须考虑数据不连续的情况(通常如果 Mat 代表更大图像的 ROI)。
  • @DanMašek。谢谢你。

标签: java opencv bytebuffer unsafe


【解决方案1】:

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

【讨论】:

  • 你能举一个如何包装地址的例子吗?
  • @zcaudate 我添加了一个简单的例子。顺便说一句,这不会在 Java 9+ 上编译,但你可以做类似的事情。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

    它还让您能够以 C 风格编写 Java 程序,手动处理内存。

    查看:https://github.com/alaisi/nalloc

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-07-16
      • 1970-01-01
      • 1970-01-01
      • 2014-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多