如何从从 java 传递到 jni 的 bytebuffer 写入和读取

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/13386176/
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 12:31:43  来源:igfitidea点击:

how to write and read from bytebuffer passing from java to jni

javaandroidc++android-ndkjava-native-interface

提问by Lan Nguyen

I need help with my android project. I want to pass a buffer from java to jni, and my C++ code will populate the data. Then java will display them on the screen. I am not familiar much with C++ and have no idea how to write to write to the buffer.

我的 android 项目需要帮助。我想将一个缓冲区从 java 传递给 jni,我的 C++ 代码将填充数据。然后java会将它们显示在屏幕上。我对 C++ 不太熟悉,也不知道如何写入缓冲区。

this is what i got. in java

这就是我得到的。在 Java 中

ByteBuffer bb = ByteBuffer.allocateDirect(216);
        IssmJni.processBuffer(bb);

native method

本地方法

public static native void processBuffer(ByteBuffer bb);

I don't use jni_onload, so no javah in C++

我不使用 jni_onload,所以 C++ 中没有 javah

static void fillBuffer(JNIEnv *env, jclass clazz, jobject buf)
    {
        double *dBuf = env->GetDirectBufferAddress(env, buf);

    }

I am stuck here, can I do double dbuf? or is it has to be a char?

我被困在这里,我可以做双dbuf 吗?或者它必须是一个字符

Let said I want to write 1,2,3,4,5 to this dbuf, how do I do it? i am thinking of dbuf.put(1); ... dbuf.put(5) but it is not working. and after populating it, do I just call bb.get(position) in java?

假设我想将 1,2,3,4,5 写入这个 dbuf,我该怎么做?我在想 dbuf.put(1); ... dbuf.put(5) 但它不起作用。在填充它之后,我是否只在 java 中调用 bb.get(position) ?

Someone clarify this for me please, example would be appreciated Thank you

请有人为我澄清这一点,示例将不胜感激谢谢

this is my table of native methods

这是我的本地方法表

static JNINativeMethod method_table[] = {

静态 JNINativeMethod method_table[] = {

{"fac"      ,     "(J)J" , (void *) factorial},
    {"getBuffer",     "()[D" , (void *) getBufferNative},
    //{"processBuffer", "(Ljava/nio/ByteBuffer)V", (void *) fillBuffer}};

The other two works fine except the last one.

除了最后一个之外,其他两个工作正常。

回答by Devunwired

I don't use jni_onload, so no javah in C++

我不使用 jni_onload,所以 C++ 中没有 javah

It may be irrelevant to your question, but you sort of have to do one or the other. You either need to do your Java-to-Native method mapping in the onLoad function or use javah to generate the method signatures that JNI can pick up at runtime. Otherwise your native methods will never be invoked.

这可能与您的问题无关,但您必须做一个或另一个。您要么需要在 onLoad 函数中进行 Java 到本机方法的映射,要么使用 javah 生成 JNI 可以在运行时获取的方法签名。否则你的本地方法将永远不会被调用。

If your native method is properly being called, however, whatever you are doing is probably fine.

但是,如果您的本机方法被正确调用,则无论您做什么都可能没问题。

I am stuck here, can I do double dbuf? or is it has to be a char?

我被困在这里,我可以做双 dbuf 吗?或者它必须是一个字符?

The return value of the function is actually a void*, so you can cast it to whatever pointer type you want since it is just a memory address. However, the actual data type of the direct buffer will be jbyte, which is a typedef of signed char, so the following is probably best:

该函数的返回值实际上是 a void*,因此您可以将其强制转换为您想要的任何指针类型,因为它只是一个内存地址。但是,直接缓冲区的实际数据类型将是jbyte,它是 的 typedef signed char,因此以下可能是最好的:

jbyte *dBuf = env->GetDirectBufferAddress(env, buf);

Let said I want to write 1,2,3,4,5 to this dbuf, how do I do it?

假设我想将 1,2,3,4,5 写入这个 dbuf,我该怎么做?

The notation in C/C++ to access values in an array is with [] notations, i.e.:

C/C++ 中访问数组中的值的符号是 [] 符号,即:

jbyte *dBuf = env->GetDirectBufferAddress(env, buf);

dBuf[0] = 63;
dBuf[1] = 127;
// ...and so on...

and after populating it, do I just call bb.get(position) in java?

在填充它之后,我是否只在 java 中调用 bb.get(position) ?

Yes, you can use the accessor methods on ByteBufferto access the data you have written from your native code.

是的,您可以使用ByteBuffer访问器方法来访问您从本机代码编写的数据。