【问题标题】:How to cast a char* to jbyteArray in JNI whitout malloc a new memory area如何在 JNI 中将 char* 强制转换为 jbyteArray 而没有 malloc 一个新的内存区域
【发布时间】:2020-09-03 13:21:38
【问题描述】:

我有一个混合 Java 和 C 的代码,我需要将 Java 代码的 byte[] 传递给 C 代码来完成一些计算。我在 JNI 中使用以下代码将 byte[] 转换为 char*(env is JNIEnv * of三):

jboolean is_copy = JNI_TRUE;
char *native_byte_array = (char *) (*env)->GetByteArrayElements(env, byte_array, &is_copy);

我完成了 char* 类型的计算,返回值也有 char* 类型,我想用 jbyteArray 返回一个值,所以我可以在 Java 中的 byte[] 类型中使用它。我在 JNI 中尝试了以下代码( env 是 C) 的 JNIEnv *:

jbyteArray java_buffer = (*env)->NewByteArray(env, buffer_size);

(*env)->SetByteArrayRegion(env, java_buffer, 0, buffer_size, (const jbyte *) native_buffer);

NewByteArray 似乎会创建一个新的 byte[] 实例,而 SetByteArrayRegion 会将数据复制到新创建的 byte[] 中。 但是,如果我有一个需要转换为字节 [] 的大返回值,则效率不高。 那么,有没有一种方法可以在没有 malloc 新内存的情况下创建一个 jbyteArray 实例并使其指向 char* 区域?

【问题讨论】:

    标签: java c java-native-interface


    【解决方案1】:

    您可以使用NewDirectByteBuffer。 (我知道,它与 byte[] 不同,但它非常接近) 返回:

    //Do something...
    char* result=...;
    return (*env)->NewDirectByteBuffer(env, result, buffer_size);
    

    通过:

    JNIEXPORT jobject JNICALL Java_Foo_bar(JNIEnv* env,jclass cls, jobject buffer){
      char* bufferPassedFromJava=(*env)->GetDirectBufferAddress(env,buffer);//May return NULL
    }
    

    这些 DirectByteBuffers 只是对 long(地址)的一个小包装器,因此您可以在不复制数组的情况下使用它们

    【讨论】:

    • 谢谢。使用 GetDirectBufferAddress 和 NewDirectByteBuffer 方法帮助我在 Java 中的 byte[] 和 JNI 中的 char* 之间转换数据。但是,NewDirectByteBuffer 的返回值是一个 DirectByteBuffer 实例,它 hasArray() 返回 false 和数组() 方法不受支持。如果我想获取 DirectByteBuffer 实例中的原始字节 [],我需要使用 ByteBuffer.get(int index) 循环遍历 DirectByteBuffer 实例中的原始字节 [] 并复制到新的byte[]。这几乎和使用 NewByteArray 和 SetByteArrayRegion 一样。
    • 您可以编写自己的DirectByteBuffer 实现,实现ByteBuffer,并使用您需要的所有方法。这个类有一个长属性,从那里,byte[] 被懒惰地复制到一个字节数组,因为你总是必须复制数组。
    • 你说得对,我总是要复制数组。我会选择合适的方法。
    • 长长的(地址) long 值不足以保存地址。 64 位 Windows 上的地址是 64 位,但 64 位 Windows 上的 long 只有 32 位。
    • 我的意思是Java long(64位)。 @AndrewHenle
    猜你喜欢
    • 2012-01-16
    • 2013-11-11
    • 2019-12-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-01-04
    相关资源
    最近更新 更多