直接字节缓冲区 [英] Direct ByteBuffer

查看:105
本文介绍了直接字节缓冲区的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在用JNI测试直接的ByteBuffer(java.nio.ByteBuffer).因此,以下代码尝试执行以下操作:

I am testing out direct ByteBuffer(java.nio.ByteBuffer) with JNI. So the code below tries to:

  1. 将值放入Java中的直接ByteBuffer
  2. 更改C ++中的值
  3. 获取Java中的值

我想知道我到底在哪里做错了? C ++代码设法从Java获取数据,但是C ++中的更改未在Java中反映出来.

I was wondering where exactly did I do wrong? The C++ code manage to get the data from Java but changes in C++ did not reflect back in Java.

这是我在java上所做的:

This is what I did on java:

public static void main(String[] args){
    ByteBuffer bb = ByteBuffer.allocateDirect(3);
    byte[] b = {122,121,120};
    System.out.println("1: " + new String(b));
    bb.put(b);

    new JNI.process(bb);

    byte[] c = new byte[3];
    c[0] = bb.get();
    System.out.println("4: " + new String(c));
}

这是我对JNI函数所做的:

This is what I did on JNI function:

JNIEXPORT void JNICALL Java_MarsJNI_mapreduce
  (JNIEnv *env, jobject thisObj, jobject output){
    char *out = (char*)env->GetDirectBufferAddress(output);
    printf("2: %s\n", out);
    out = "ABC";
    printf("3: %s\n", out);
}

我得到的结果是:

1: zyx
2: zyx
3: ABC
Exception in thread "main" java.nio.BufferUnderflowException
    at java.nio.Buffer.nextGetIndex(Buffer.java:474)
    at java.nio.DirectByteBuffer.get(DirectByteBuffer.java:208)
    at MarsJNI.main(MarsJNI.java:21)

推荐答案

第一个问题:请参见@TedBigham的答案.您也可以使用buf.rewind().

First problem: see @TedBigham's answer. You can also use buf.rewind().

第二个问题:您仅将缓冲区的第一个字节复制到c中,而不是整个缓冲区中.做:

Second problem: you only copy the first byte of the buffer into c, not the whole buffer. Do:

byte[] c = new byte[3];
bb.rewind();
bb.put(c);
System.out.println("4: " + new String(c));

第三个问题:您的C ++代码确实存在:

Third problem: your C++ code does:

char *out = (char*)env->GetDirectBufferAddress(output);
// ...
out = "ABC";

但是您在这里要做的是创建{ 'A', 'B', 'C', 0 }并将其分配给out;您实际上并没有修改缓冲区的内容.您应该这样做:

But what you do here is create { 'A', 'B', 'C', 0 } and assign out to it; you don't actually modify the content of the buffer. You should do:

memcpy(out, "ABC", 3);

第四个问题:在byte[]中创建String时,应指定编码:

Fourth problem: when you create a String out of a byte[], you should specify the encoding:

new String(c, StandardCharsets.UTF_8);

这篇关于直接字节缓冲区的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆