代码之家  ›  专栏  ›  技术社区  ›  ata

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

  •  5
  • ata  · 技术社区  · 16 年前

    我已经发布了一个关于它的问题,但当时我还没有账户。我得到了一个答复,但我还是很困惑,我不能继续讲下去。

    我正在重新发布该问题,并链接到上一个对话。

    Returning char array from java to string - JNI

    我在Java中存储的数据被序列化。我使用下面的代码做一个Java函数调用。

    下面的代码假定C的char与Java字节兼容,因为Java的字符是2字节,而C字符是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调用,并且在检索数据后,我的控件应该返回到C程序。我对代码的工作方式有点困惑。如何获取指向数组的指针(从Java中检索),然后使用GETBYTAREAR元素检索它。请记住,我不知道在手之前要检索的数据的大小,因此不能使用NexBytErar函数创建字节数组,然后用Java代码填充数据。

    2 回复  |  直到 16 年前
        1
  •  12
  •   ata    16 年前

    好吧,我算了算。我把它放在这里,这样其他人也可以利用它。

    考虑下面的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);
    }
    

    我已经检查过了,它工作了。我现在要检查二维数组。我想它会和这个一样,只有你能得到jobjectarray,这个数组的每个元素都是一个jbytearray。

        2
  •  1
  •   Kate Gregory    15 年前

    非常感谢你!我试图通过一个从C到Java和Java的双数组,然后返回一个更新的双数组到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