2009-08-05 10 views
5

Ich habe bereits eine Frage dazu geschrieben, aber zu diesem Zeitpunkt habe ich nicht das Konto. Ich bekam eine Antwort, aber ich war immer noch verwirrt und ich kann diesen Thread nicht fortsetzen.Abrufen von Byte-Array unbekannter Länge aus Java-Speicher

Ich bin re die Frage wieder zusammen mit einem Link zum vorherigen Gespräch veröffentlichen.

Returning char array from java to string - JNI

Die Daten, die ich in Java bin Speicherung serialisiert. Ich mache einen Java-Funktionsaufruf mit folgendem Code.

Der folgende Code geht davon aus, dass char von C mit dem Byte von Java kompatibel ist, weil char von Java von 2 Bytes ist, während der C char von 1 Byte ist. Die jbyte ist auch ein signed char *

//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); 

}

Nachdem ich die Daten gespeichert haben, verwende ich eine andere Funktion Daten aus dem Speicher abgerufen werden. Zu diesem Zeitpunkt weiß ich nicht, wie groß die Daten sind, die ich abrufen werde. Meine API ist in C und Store ist in Java. Ich werde meine C-Funktionen verwenden, um mit Java zu interagieren. Außerdem können mehrere Threads gleichzeitig Daten aus dem Java-Speicher abrufen.

Ich bilde Anrufe von C nach Java und meine Kontrolle soll nach Abrufen von Daten zu C-Programm zurückzukehren. Ich bin ein wenig verwirrt darüber, wie der Code funktioniert. Wie bekomme ich Zeiger auf Array (abgerufen von Java) und dann abrufen Sie mit GetByteArrayElements. Denken Sie daran, dass ich die Größe der Daten, die ich vorher abrufen werde, nicht kenne und daher kein Byte-Array mit der NewByteArray-Funktion erstellen und später mit Daten in Java-Code füllen kann.

Antwort

12

Ok, ich habe es ausgerechnet. Ich werde es hier niederlegen, damit andere es auch nutzen können.

ich die folgende Java-Methode, die einen Byte-Array (um nur Dummy-Code, keine Schecks usw.) liefert

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

und auf C-Seite, können Sie das byte [] folgend

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); 
} 
abrufen

Ich habe es überprüft und es funktioniert. Ich werde es jetzt für 2-D-Array überprüfen. Ich denke, es wäre das gleiche wie das nur du würdest jobjectArray bekommen und jedes Element dieses Arrays ist ein jbyteArray.

+0

Danke Ich habe genau das gleiche Problem und dieser Code war hilfreich. In Visual Studio musste ich einige Würfe enthalten, um es aber zu kompilieren, ich hatte den Rückgabewert von CallStaticObjectMethod mit (jbyteArray) zu werfen, und ich hatte den Rückgabewert von GetByteArrayElements mit (char *) zu werfen –

+0

Vielen Dank dafür! 4 Jahre später stieß ich auf das gleiche Problem in den env-> Methoden, die nicht zum Lesen in einem Byte-Array-Feld arbeiten. Diese Lösung hat funktioniert :) – blkhatpersian

1

Vielen Dank! Ich habe versucht, ein Doppel-Array von C an Java übergeben und Java wiederum ein erneuertes Doppel-Array an C. Dies ist ein Teil von JNI, wo ich versuche, einen Java-Code mit Fortran-Quellcode zu verknüpfen. Aber Fortran-Code muss einen weiteren Java-Code für einige Berechnungen aufrufen. Also mache ich Java zu C nach Fortran zu C nach Java mit JNI. Lösung zum Senden eines Doppel-Array von C nach Java und Java, die ein Doppel-Array zu C zurückgibt, ist hier.

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 
+0

Danke.Ich hoffe, es wird anderen helfen – ata

Verwandte Themen