从Java存储中检索未知长度的字节数组

我已经发布了一个关于它的问题,但那时我还没有账号。 我得到了答复,但我仍然感到困惑,我不能继续这个post。

我将再次发布问题以及之前对话的链接。

将char数组从java返回到字符串 – JNI

我用Java存储的数据是序列化的。 我使用下面的代码进行java函数调用。

下面的代码假定C的char与Java的字节兼容,因为Java的char是2字节而C的char是1字节。 jbyte也是一个签名的字符*

//value will be the serialized data void store(char* key, char* value, int val_len) 

{

  //consider the jclass and methodid are already initialized jstring j_key = (*env)->NewStringUTF(env, key); jbyteArray j_value = (*env)->NewByteArray(env, val_len); (*env)->SetByteArrayRegion(env, j_value, 0, val_len, (jbyte *)value); //The store method on java side will save the value (as is) in memory (*env)->CallStaticVoidMethod(j_class, store_method, key, value); (*env)->ReleaseByteArrayElements(env, j_value, (jbyte *)value, JNI_ABORT); (*env)->ReleaseStringUTFChars(env, j_key, key); 

}

保存数据后,我使用另一个函数从商店检索数据。 那时我不知道我要检索的数据大小。 我的API在C中,而商店是在Java中。 我将使用我的C函数与Java交互。 并且还可以有多个线程同时从Java存储中检索数据。

我正在从C调用Java到Java,我的控件应该在检索数据后返回到C程序。 我对代码如何工作有点困惑。 我将如何获取指向数组的指针(从java检索),然后使用GetByteArrayElements检索它。 记住我不知道我要在手边检索的数据大小,因此不能使用NewByteArray函数创建一个字节数组,然后用java代码中的数据填充它。

好的,我把它弄清楚了。 我会把它放在这里,以便其他人也可以利用它。

考虑以下返回字节数组的java方法(只是一个虚拟代码,没有检查等)

 public static byte[] GetData(){ return myStore.getData(); } 

在C端,您可以检索字节[]如下

  void get_data() { int len = 0; char* value = NULL; /*Consider j_class, and j_methodid are already initialized*/ jbyteArray j_value = (*env)->CallStaticObjectMethod(env, j_class, j_methodid); if(j_value != NULL) { len = (*env)->GetArrayLength(env, j_value); value = (*env)->GetByteArrayElements(env, j_value, NULL); } /*later on release the resource*/ (*env)->ReleaseByteArrayElements(env, j_value, value, 0); } 

我检查了它,它的工作原理。 我现在要检查二维arrays。 我认为只有你得到jobjectArray,并且这个数组的每个元素都是jbyteArray。

非常感谢你! 我试图将一个双数组从C传递给Java,而java又将一个更新的double数组返回给C.这是JNI的一部分,我试图将Java代码链接到Fortran源代码。 但Fortran代码必须再调用一个Java代码进行一些计算。 所以我正在使用JNI从Java到C到Fortran到C到Java。 将双数组从C发送到Java的解决方案和Java将双数组返回到C的解决方案就在这里。

 jdoubleArray tempA = (jdoubleArray)(*envG)->NewDoubleArray(envG,3); //create an array with 3 elements to be sent to Java jdoubleArray tempB = (jdoubleArray)(*envG)->NewDoubleArray(envG,3); //This is will be //assigned to returned java double array (*envG)->SetDoubleArrayRegion(envG,tempA,0,3,(const jdouble *)arr);//need to send the //tempA array to Java. "arr" is the double array coming to C from Fortran! int leng = 0; for (i = 0; i < 1; i++) { //sending an array "tempA" to Java. Java returns tempB, a double array tempB = (*envG)->CallObjectMethod(envG, obj_print, id_print,(*A),(*B),(*C),tempA); if (tempB != NULL){ for (k = 0; k < 3; k++){ leng = (*envG)->GetArrayLength(envG, tempB); jdouble* value = (*envG)->GetDoubleArrayElements(envG, tempB, NULL); printf("FROM JAVA ARRAY %f\n", value[k]); } //end for } //end if