问题描述
我有一个混合了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只是简化了一个长长度(地址)周围的小包装,因此您可以在不复制数组的情况下使用它们