首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >直接ByteBuffer

直接ByteBuffer
EN

Stack Overflow用户
提问于 2014-03-15 11:25:14
回答 2查看 1.7K关注 0票数 1

我正在用JNI测试直接ByteBuffer(java.nio.ByteBuffer)。因此,下面的代码试图:

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

我在想我到底做错了什么?C++代码设法从Java中获取数据,但是C++中的变化并没有在Java中反映出来。

这就是我在java上所做的:

代码语言:javascript
复制
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函数所做的:

代码语言:javascript
复制
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);
}

我得到的结果是:

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-03-15 12:14:40

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

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

代码语言:javascript
复制
byte[] c = new byte[3];
bb.rewind();
bb.put(c);
System.out.println("4: " + new String(c));

第三个问题:您的C++代码:

代码语言:javascript
复制
char *out = (char*)env->GetDirectBufferAddress(output);
// ...
out = "ABC";

但是,这里所做的是创建{ 'A', 'B', 'C', 0 }并将out分配给它;实际上并不修改缓冲区的内容。你应该这样做:

代码语言:javascript
复制
memcpy(out, "ABC", 3);

第四个问题:当您从一个String中创建一个byte[]时,您应该指定编码:

代码语言:javascript
复制
new String(c, StandardCharsets.UTF_8);
票数 3
EN

Stack Overflow用户

发布于 2014-03-15 11:34:39

我认为在调用bb.position()之前,需要调用bb.get(0)。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22423147

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档