如何使用 JNI 将 Java ByteBuffer 发送到 C?
How to send Java ByteBuffer to C using JNI?
首先,我想说旧答案现在不起作用(例如,下面答案中的 GetDirectBufferAddress 函数现在需要一个参数),如下所示:
JNI - native method with ByteBuffer parameter
在这里,
how to write and read from bytebuffer passing from java to jni
如果有人帮忙就更好了..
因此,我无法使用 JNI 从 Java 将填充了一些元素的 ByteBuffer 正确发送到 C,并且我无法 return 将 ByteBuffer 的元素再次发送到 C
我的原生函数decleration:
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 程序时它抛出异常。我怎样才能 return 我从 C 中填充的 ByteBuffer 值?
编辑
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x719c16b8, pid=1096, tid=1900
要使用 GetDirectBufferAddress()
,您必须保证 pkt 是 direct(您可以使用 isDirect() 进行检查).获取此类对象的简单方法是ByteBuffer.allocateDirect()
。 Direct ByteBuffer 也可以从 C++ 创建。
直接和间接 ByteBuffer 的区别在 Java oficial doc.
中有清楚的解释
更新 我看到你的更新了。不,ByteBuffer.allocate(1000)
不产生 DirectByteBuffer。
正如 @Tom Blodget correctly , the JNI spec 明确指出 GetDirectBufferAddress()
可以 return NULL。这是双向的:如果 pkt 是一个间接的 ByteBuffer,调用本身不应该崩溃,但是即使你确定 pkt 是一个 DirectByteBuffer。
你不能使用 GetDirectBufferAddress()
除了直接字节缓冲区。您没有直接字节缓冲区。
首先,我想说旧答案现在不起作用(例如,下面答案中的 GetDirectBufferAddress 函数现在需要一个参数),如下所示:
JNI - native method with ByteBuffer parameter
在这里,
how to write and read from bytebuffer passing from java to jni
如果有人帮忙就更好了..
因此,我无法使用 JNI 从 Java 将填充了一些元素的 ByteBuffer 正确发送到 C,并且我无法 return 将 ByteBuffer 的元素再次发送到 C
我的原生函数decleration:
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 程序时它抛出异常。我怎样才能 return 我从 C 中填充的 ByteBuffer 值?
编辑
A fatal error has been detected by the Java Runtime Environment:
EXCEPTION_ACCESS_VIOLATION (0xc0000005) at pc=0x719c16b8, pid=1096, tid=1900
要使用 GetDirectBufferAddress()
,您必须保证 pkt 是 direct(您可以使用 isDirect() 进行检查).获取此类对象的简单方法是ByteBuffer.allocateDirect()
。 Direct ByteBuffer 也可以从 C++ 创建。
直接和间接 ByteBuffer 的区别在 Java oficial doc.
中有清楚的解释更新 我看到你的更新了。不,ByteBuffer.allocate(1000)
不产生 DirectByteBuffer。
正如 @Tom Blodget correctly GetDirectBufferAddress()
可以 return NULL。这是双向的:如果 pkt 是一个间接的 ByteBuffer,调用本身不应该崩溃,但是即使你确定 pkt 是一个 DirectByteBuffer。
你不能使用 GetDirectBufferAddress()
除了直接字节缓冲区。您没有直接字节缓冲区。