java 从 JNI 操作 ByteBuffer

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11329519/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 04:40:59  来源:igfitidea点击:

Manipulation of ByteBuffer from JNI

javajava-native-interfacebytebuffer

提问by gonzus

I need to pass a (direct) ByteBufferto native functions that will read/write from/into the buffer. Once these operations are completed, I would like to access the ByteBufferfrom Java code using the regular functions; in particular, limit()and position()should reflect the current state of the buffer.

我需要将一个(直接)传递给ByteBuffer将从/向缓冲区读/写的本机函数。完成这些操作后,我想ByteBuffer使用常规函数访问from Java 代码;特别是,limit()position()要体现缓冲器的当前状态。

Since JNI will use GetDirectBufferAddress()to directly access the underlying buffer, I am assuming I should call flip ()/ limit()/ position()after I am done reading / writing. However, I have been unable to make this work. For example, after I read a couple of bytes into the buffer from C, and set its limit and position accordingly, I cannot query those bytes from Java; Java's idea of the buffer limit and position are not consistent with what I did in the C code.

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

Can anybody point me to a working example of this? Thanks in advance.

任何人都可以指出我的工作示例吗?提前致谢。

回答by maba

You could let your native method return the number of written bytes. Then update the ByteBuffer accordingly on the Java side.

您可以让您的本机方法返回写入的字节数。然后在 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);
        }
        ...
    }
}


Edit

编辑

Trying out to set the limit value on the C side is working too so I don't know why you have problems with it.

尝试在 C 端设置限制值也很有效,所以我不知道你为什么会遇到问题。

Naive implementation (nothing cached etc.):

幼稚的实现(没有缓存等):

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;
}

The limit is set on the buffer when inspecting on Java side.

在 Java 端检查时在缓冲区上设置限制。