如何使用JNI将Java ByteBuffer发送到C?

时间:2017-11-08 08:56:33

标签: java c java-native-interface native bytebuffer

首先,我想说现在的旧答案不起作用(例如,下面的答案中的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

2 个答案:

答案 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()。你没有直接的字节缓冲区。