如何从java传递给jni的字节缓冲区中进行写和读

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

本文关键字:缓冲区 字节 java jni      更新时间:2023-10-16

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

这就是我得到的。在java 中

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

本地方法

public static native void processBuffer(ByteBuffer bb);

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

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

我被困在这里了,我能做双倍的dbuf吗?还是必须是一个字符?

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

有人帮我澄清一下,举个例子就好了谢谢

这是我的原生方法表

静态JNINativeMethod method_table[]={

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

除最后一个外,其他两个都很好。

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

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

然而,如果您的本机方法被正确地调用,那么您所做的一切都可能是好的。

我被困在这里,我能做双倍dbuf吗?还是必须是一个字符?

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

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

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

C/C++中访问数组中值的表示法使用[]表示法,即:

jbyte *dBuf = env->GetDirectBufferAddress(env, buf);
dBuf[0] = 63;
dBuf[1] = 127;
// ...and so on...

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

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