英文:
How to cast a char* to jbyteArray in JNI whitout malloc a new memory area
问题
我有一段混合了Java和C的代码,我需要将一个Java代码的byte[]传递给C代码,以执行一些计算。我通过在JNI中使用以下代码将byte[]转换为char*:
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[]中。然而,如果我有一个需要转换为byte[]的大型返回值,这样做效率并不高。所以,是否有一种方法可以创建一个jbyteArray实例,而无需分配新的内存,并使它指向char*区域?
英文:
I have a code mixed Java and C, I need pass a byte[] of Java code to C code to complete some calculate.I convert byte[] to char* by using below code in JNI(env is JNIEnv * of C):
jboolean is_copy = JNI_TRUE;
char *native_byte_array = (char *) (*env)->GetByteArrayElements(env, byte_array, &is_copy);
I finished calculate with type char* and the return value has type char* too,I want to return a value with jbyteArray so I can use it in type byte[] in Java.I have try the below code in JNI(env is JNIEnv * of C):
jbyteArray java_buffer = (*env)->NewByteArray(env, buffer_size);
(*env)->SetByteArrayRegion(env, java_buffer, 0, buffer_size, (const jbyte *) native_buffer);
It seems like that NewByteArray will create a new byte[] instance and SetByteArrayRegion will copy data into the new created byte[].
However,it's not efficient if I have a big return value that need to be cast to byte[].
So,is there a way that can create a jbyteArray instance without malloc new memory and make it point to the char* area?
答案1
得分: 1
你可以使用NewDirectByteBuffer
。(我知道,它与byte[]
不完全相同,但非常接近)
返回:
//做一些操作...
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);//可能返回NULL
}
这些DirectByteBuffer
实际上只是一个围绕长整型(地址)的小包装器,因此您可以在不复制数组的情况下使用它们。
英文:
You could use NewDirectByteBuffer
. (I know, it's not the same as a byte[], but it comes quite near)
To return:
//Do something...
char* result=...;
return (*env)->NewDirectByteBuffer(env, result, buffer_size);
To pass:
JNIEXPORT jobject JNICALL Java_Foo_bar(JNIEnv* env,jclass cls, jobject buffer){
char* bufferPassedFromJava=(*env)->GetDirectBufferAddress(env,buffer);//May return NULL
}
These DirectByteBuffers are, simplified just a small wrapper around a long (The address), so you can use them without copying arrays around
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论