2009-08-05 39 views
5

我已經發布了一個關於它的問題,但那時我還沒有賬戶。我得到了答覆,但我仍然感到困惑,我無法繼續這個話題。從Java商店檢索未知長度的字節數組

我再次發佈該問題以及與之前對話的鏈接。

Returning char array from java to string - 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代碼中的數據填充它。

回答

12

好吧,我想通了。我會把它放在這裏,以便其他人也可以利用它。

考慮到返回一個字節數組(只是一個虛設碼,沒有支票等)

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

和C側下面的java方法,可以檢索字節[]如下

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。

+0

謝謝我遇到了完全相同的問題,這段代碼很有幫助。在VisualStudio中,我必須包含一些強制轉換才能編譯它,但我必須使用(jbyteArray)從CallStaticObjectMethod中返回值,並且必須使用(char *) – 2009-08-28 22:19:32

+0

從GetByteArrayElements強制返回值謝謝! 4年後,我在env->方法中遇到了同樣的問題,無法讀取字節數組字段。此解決方案工作:) – blkhatpersian 2014-03-11 23:00:30

1

非常感謝!我試圖從C傳遞一個double數組到Java,並且java又向C返回一個更新的雙數組。這是JNI的一部分,我嘗試將Java代碼鏈接到Fortran源代碼。但Fortran代碼必須再調用一次Java代碼才能進行一些計算。所以我正在使用JNI從Java到C到Fortran到C到Java。 發送從C到Java的雙數組以及向C返回雙數組的Java解決方案就在這裏。

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