首先,我想说现在的旧答案不起作用(例如,下面的答案中的GetDirectBufferAddress函数现在想要一个参数),如下所示:
JNI - native method with ByteBuffer parameter
在这里,
how to write and read from bytebuffer passing from java to jni
如果有人帮忙会更好..
所以,我无法使用JNI正确地将我的ByteBuffer(其填充的一些元素)发送给C,而我无法再将该ByteBuffer的元素返回给C < / p>
我的原生功能声明:
public native int myfunc(ByteBuffer pkt);
分配
private ByteBuffer pkt = ByteBuffer.allocate(1000);
我这样称呼它:
System.out.println(myfunc(pkt)); // Doesn't works, throws exception
pkt.position(0);
System.out.println(pkt.get()); // works, when I do comment line above .println
我的C代码如下:
JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *, jobject, jobject); // header
JNIEXPORT jint JNICALL Java_xxx_myfunc(JNIEnv *env, jobject obj, jobject pkt) // function
{
jbyte *buff = (jbyte *) env->GetDirectBufferAddress(pkt);
// buff[0] = 0; I've also tried in this way
return buff[0];
//return 1; if I return 1, it returns correctly
}
当我运行java程序时,它抛出异常。如何从C中返回填充的ByteBuffer值?
修改
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x719c16b8, pid=1096, tid=1900
答案 0 :(得分:5)
要使用GetDirectBufferAddress()
,您必须保证 pkt 直接(您可以使用isDirect()进行检查)。获取此类对象的简便方法是ByteBuffer.allocateDirect()
。 Direct ByteBuffer也可以从C ++创建。
直接和间接的ByteBuffer之间的区别在Java oficial doc中有明确解释。
更新我看到了您的更新。不,ByteBuffer.allocate(1000)
不会产生DirectByteBuffer。
正确@Tom Blodget正确noted,JNI spec明确表示GetDirectBufferAddress()
可以返回NULL。这有两种方式:如果 pkt 是间接的ByteBuffer,则调用本身不会崩溃,但即使您确定 pkt 是DirectByteBuffer,也必须检查结果。< / p>
答案 1 :(得分:0)
除直接字节缓冲区外,不能使用GetDirectBufferAddress()
。你没有直接的字节缓冲区。