den*_*yan 2 c java java-native-interface bytebuffer native
首先,我想说旧的答案不起作用(例如,下面的答案中的GetDirectBufferAddress函数现在想要一个参数),如下所示:
和这里,
如果有人帮忙会更好..
因此,我无法使用JNI正确地将我的ByteBuffer(其中一些元素已填充)从Java发送到C,并且我无法将该ByteBuffer的元素再次返回到C
我的本地功能解除:
public native int myfunc(ByteBuffer pkt);
Run Code Online (Sandbox Code Playgroud)
分配给它
private ByteBuffer pkt = ByteBuffer.allocate(1000);
Run Code Online (Sandbox Code Playgroud)
我这样称呼它:
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
Run Code Online (Sandbox Code Playgroud)
我的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
}
Run Code Online (Sandbox Code Playgroud)
当我运行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
Run Code Online (Sandbox Code Playgroud)
要使用GetDirectBufferAddress()你必须保证pkt是直接的(你可以用isDirect()来检查).获得这样的对象的简单方法是ByteBuffer.allocateDirect().Direct ByteBuffer也可以从C++创建.
直接和间接的ByteBuffer之间的区别在Java oficial doc中有清楚的解释.
更新我看到你的更新.不,ByteBuffer.allocate(1000)不会产生DirectByteBuffer.
正如@Tom Blodget正确指出的那样,JNI 规范明确表示GetDirectBufferAddress()可以返回NULL.这有两种方式:如果pkt是间接的ByteBuffer,则调用本身不会崩溃,但即使您确定pkt是DirectByteBuffer ,也必须检查结果.