# [jni] jbytearray <-> byte array



## darkeye2 (20. Jan 2012)

Hallo,

google mag mich mal wieder nicht (oder ich finde nicht den passenden suchbegriff), auf jeden fall versuche ich grad ein jbytearray in eine normales c(++) byte array umzuwandeln und zum schluss noch ein byte array in ein jbyte array, leider will keins von beiden klappen. Dank google hab ich jetzt mindestens 10 verschiedene methode, die keine wirklich funktioniert, könnte mir jemand bitte eine (möglichst einfache) funktionierende möglichkeit für beide umwandlungen posten?

Danke in vorraus.

MfG
darkeye


----------



## Marco13 (20. Jan 2012)

"Umwandeln"... hm. Willst du die Daten aus dem jbyteArray nur für irgendeine Rechnung lesen, oder irgendwie länger auf C-Seite speichern...? Referenz ist im Zweifelsfall das, was auf Basic Types, Strings, and Arrays steht... Kann man genauer sagen, wo's hakt?


----------



## darkeye2 (21. Jan 2012)

ich verwende die daten um sie an eine methode zu übergeben, die wiederrum ein byte array zurückgibt, dass ich wieder an mein java prog zurückgeben will, leider scheint irgendwas schief zu laufen, da mein prog immer abstürzt, so sieht dier betroffene code aus:


```
//nötige variablen
       BYTE *recieveData;
       BYTE *sendData; 
       DWORD len = 16;
       DWORD *sendedDataLength;
       DWORD *recieveDataLength;

//jbytearray in byte array umwandeln (scheint zu klappen, bin mir zwar nicht hundert prozentig sicher, aber fast)
       jbyte *dataArr = env->GetByteArrayElements(b, 0);  //b ist das übergebene jbytearray
       for(int i = 0; i<4; i++){
          sendData[i] = dataArr[i]; 
       }

//meine methode, die ihrerseits recieveData einen wert zuweist
MPRead(inPipe, recieveData, len, recieveDataLength, timeout)

//bis hierhin läuft das prog noch, doch in der folgenden schleife stürzt es sofort ab, ziel ist es, das byte array in ein jbytearray umzuwandeln
       jbyteArray result = env->NewByteArray(4);
       jbyte *bytes = env->GetByteArrayElements(result, 0);
       for(int k = 0; k<4;k++){
          bytes[k] = recieveData[k];
       }
       env->SetByteArrayRegion(result, 0, 4, bytes );
```


----------



## Marco13 (21. Jan 2012)

Hm... ist schon spät, und ... ich gehe davon aus, dass dort irgendwo ein "new" oder "malloc" vorkommt, weil es sonst viel früher und überschaubarer abkacheln würde, aber... beim ersten drüberschauen sehe ich nirgendwo ein ReleaseByteArrayElements... kann's sein, dass du stattdessen(!?) SetByteArrayRegion verwendet hast?! Grob sowas wie

```
//jbytearray in byte array umwandeln ...
       jbyte *dataArr = env->GetByteArrayElements(b, 0);  //b ist das übergebene jbytearray
       for(int i = 0; i<4; i++){
          sendData[i] = dataArr[i]; 
       }

       // Abort: Nichts zurüchschreiben, 'b' wurde nur gelesen und wird jetzt nicht mehr gebraucht
       env->ReleaseByteArraElements(b, dataArr, JNI_ABORT); 
 
...
       //bis hierhin läuft das prog noch, doch in der folgenden schleife stürzt es sofort ab...
       jbyteArray result = env->NewByteArray(4);
       jbyte *bytes = env->GetByteArrayElements(result, 0);
       for(int k = 0; k<4;k++){
          bytes[k] = recieveData[k];
       }
       // Das 0 als letzter parameter heißt: Schreib' die daten ggf. zurück 
       env->ReleaseByteArrayElements(result, bytes, 0);
```

Als Alternative kann man in diesem Fall auch GetPrimitiveArrayCritical in Erwägung ziehen.


EDIT: Nebenbei: Eigentlich müßte man nach etlichen dieser Methoden (nämlich bei allen, zu denen unter JNI Functions irgendwas mit "Throws" steht) ein 
if (env->ExceptionCheck()) { ... so schnell wie möglich zurück zu Java ... }
machen... Ja, wird schnell unübersichtlich...


----------



## darkeye2 (21. Jan 2012)

hi, schonmal danke für deine hilfe, aber es klappt immer noch nicht, ich hab ein c byte array, was auf folgende weise "entstanden" ist:

BYTE *recieveData = new BYTE[4];
//übergabe des pointers an eine methode, die das array befüllt.

dannach kann ich mir die 4 elemente ausgeben lassen, also das array ist definitief voll und hat 4 elemente, nun will es es als jbytearray zurückgeben, aber kriege nur eine NullPointerException.


```
jbyteArray result = env->NewByteArray(4);
       jbyte *bytes = env->GetByteArrayElements(result, 0);
       printf("array bytes: %u", sizeof(recieveData));
       for(int k = 0; k<4;k++){
          printf("  byte: %d", recieveData[k]);
          printf("\r\n");
          bytes[k] = recieveData[k];
       }
       env->ReleaseByteArrayElements(result, bytes, 0);
```


----------



## Marco13 (22. Jan 2012)

Hm... an dem Code sieht erstmal nichts falsch aus... wo kachelt er da denn ab? Ggf. kann ich morgen oder übermorgen mal schauen, ob ein "KSKB" da hilft...


----------



## darkeye2 (22. Jan 2012)

also ich weiß wirlich nicht, wieso ich einen fotal error kriege, mein code sieht so aus:


```
JNIEXPORT jbyteArray JNICALL Java_de_ls_usb_mc_kernel_MpUsbApi_writeCMD
  (JNIEnv *env, jobject obj, jbyteArray b){
       outPipe = MPUSBOpen(0, pid_vid, out_pipe, MP_WRITE, 0);   
       inPipe = MPUSBOpen(0, pid_vid, in_pipe, MP_READ, 0);  
  
       BYTE *recieveData  = new BYTE[4]; 
       BYTE *sendData;
       DWORD len = 64;
       DWORD sendedDataLength;
       DWORD recieveDataLength;
       
       //sendData[0] = 0;
       //sendData[1] = 0;
       //sendData[2] = 0;
       //sendData[3] = 0;
       
       jbyte *dataArr = env->GetByteArrayElements(b, 0);
       for(int i = 0; i<4; i++){
          sendData[i] = dataArr[i];
       }
       env->ReleaseByteArrayElements(b, dataArr, JNI_ABORT);
       
       SendReceivePacket(sendData, 4, recieveData, &RC_LENGTH, timeout, timeout+timeout);
       
       MPUSBClose(outPipe);
       MPUSBClose(inPipe);   
        
       jbyteArray result = env->NewByteArray(4);
       jbyte *bytes = env->GetByteArrayElements(result, 0);
       printf("\r\n");
       for(int k = 0; k<4;k++){
          printf("Recieved Byte %d",k);
          printf(" : %d", recieveData[k]);
          printf("\r\n");
          bytes[k] = recieveData[k];
       }
       
       //env->SetByteArrayRegion(result, 0, 4, bytes );
       env->ReleaseByteArrayElements(result, bytes, 0);
         
      //return result;         
  }
```

wie ich der ausgabe auf der console entnehmen kann sind die werte, die das c byte array enthalten richtig, und ich weiß nicht, an welcher stelle da jetzt ein fehler auftritt, ich kriege einfach jedes mal einen fotal error und das ganze stürtzt (logischer weise) ab


----------



## darkeye2 (22. Jan 2012)

ok, also es liegt wohl nicht mal am java code, was für gründe kann es geben, dass sich die vm verabschieded?
der c code wird problemlos ausgeführt, es gibt zwar einen fehler (GetLastError()), aber dieser ist bei der funktion, die aufgerufen wird normal, und tritt fast immer auf, was nicht weiter schlimm ist, das ergebniss stimmt immer, nur mag die vm irgendwie nicht,
jemand eine idee?


----------



## Marco13 (22. Jan 2012)

Da sieht jeztz wiederum komisch aus, dass das "return" fehlt, aber insbesondere, dass "sendData" NULL (bzw. unitialisiert) ist... wenn's nicht klappt, compilier' ich das morgen vielleicht mal.


----------

