如何在JNI中将char *转换为jbyteArray,从而分配一个新的内存区域

问题描述

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

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,buffer_size,(const jbyte *) native_buffer);

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

解决方法

您可以使用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
}

这些DirectByteBuffer只是简化了一个长长度(地址)周围的小包装,因此您可以在不复制数组的情况下使用它们

相关问答

依赖报错 idea导入项目后依赖报错,解决方案:https://blog....
错误1:代码生成器依赖和mybatis依赖冲突 启动项目时报错如下...
错误1:gradle项目控制台输出为乱码 # 解决方案:https://bl...
错误还原:在查询的过程中,传入的workType为0时,该条件不起...
报错如下,gcc版本太低 ^ server.c:5346:31: 错误:‘struct...