我需要将(直接)ByteBuffer
传递给将从/向缓冲区读/写的本机函数。完成这些操作后,我想使用常规函数从Java代码访问ByteBuffer
;特别是,limit()
和position()
应该反映缓冲区的当前状态。
由于JNI将使用GetDirectBufferAddress()
直接访问底层缓冲区,我假设在读完/写入后我应该调用flip ()
/ limit()
/ position()
。但是,我一直无法做到这一点。例如,在我从C读取几个字节进入缓冲区并相应地设置其限制和位置后,我无法从Java查询这些字节; Java对缓冲区限制和位置的想法与我在C代码中所做的不一致。
有人能指出我的一个实际例子吗?提前谢谢。
答案 0 :(得分:15)
您可以让您的本机方法返回写入的字节数。然后在Java端相应地更新ByteBuffer。
public class SomeClass {
/**
* @param buffer input/output buffer
* @return number of bytes written to buffer
*/
private native int nativeMethod(ByteBuffer buffer);
public void myMethod() {
ByteBuffer buffer = ByteBuffer.allocateDirect(100);
int written = nativeMethod(buffer);
if (written > 0) {
buffer.limit(written);
}
...
}
}
修改强>
尝试在C端设置限制值也是有效的,所以我不知道你为什么遇到问题。
天真的实现(没有缓存等):
static jint nativeMethod(JNIEnv *env, jobject obj, jobject buffer) {
jclass cls = env->GetObjectClass(buffer);
jmethodID mid = env->GetMethodID(cls, "limit", "(I)Ljava/nio/Buffer;");
char *buf = (char*)env->GetDirectBufferAddress(buffer);
jlong capacity = env->GetDirectBufferCapacity(buffer);
int written = 0;
// Do something spectacular with the buffer...
env->CallObjectMethod(buffer, mid, written);
return written;
}
在Java端检查时,在缓冲区上设置了限制。