18

我需要将(直接)传递给ByteBuffer将读取/写入缓冲区的本机函数。完成这些操作后,我想ByteBuffer使用常规函数访问 Java 代码;特别是,limit()应该position()反映缓冲区的当前状态。

由于 JNI 将用于GetDirectBufferAddress()直接访问底层缓冲区,因此我假设我应该在完成读/写后调用flip ()// 。但是,我一直无法完成这项工作。例如,在我从 C 中读取几个字节到缓冲区中并相应地设置其限制和位置后,我无法从 Java 中查询这些字节;Java关于缓冲区限制和位置的想法与我在C代码中所做的不一致。limit()position()

任何人都可以指出一个可行的例子吗?提前致谢。

4

1 回答 1

19

您可以让您的本机方法返回写入的字节数。然后在 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 端进行检查时,在缓冲区上设置了限制。

于 2012-07-04T12:58:50.383 回答