2013-02-28 7 views
5

Mam tu naprawdę duży problem. Próbuję przekazać bajt [] z Java do C++ i otrzymuję wartości ujemne po konwersji. Postanowiłem, że problem polega na tym, że w bajcie Java [] są unikalne znaki [], które po przekonwertowaniu i zrobieniu dziennika mają wartości 0 lub ujemne.Konwersja bajtu JNI Java [] na C++ bytearray, zwracanie 0

Próbowałem używać bajt testowy [] znaków ciągów i działa dobrze.

Oto mój kod, jeśli to pomaga.

Java

public static native void SendMessage(byte[] message, int size); //size = message.length 

C++

static void SendMessage(JNIEnv *env, jclass cls, jbyteArray array, jint array_length) 
{ 
    jbyte* content_array = (env)->GetByteArrayElements(array,NULL); 
    //*env->GetByteArrayRegion(array,0,array_length,content_array); //tried this as well, same results 
    LOGD("content:\n"); 
    for (int i=0; i < array_length; i++) 
    { 
     LOGD("%d",content_array[i]); 
    } 

    //EDIT 
    SendMessage(client, (uint8_t*)content_array, array_length); //<- could the problem be at the point where I convert it to uint8_t? 

     (env)->ReleaseByteArrayElements(array,content_array,0); 
    } 

Wyjście

content: 48 
content: 23 
content: 13 
content: 56 
content: 0 // <--- the problem starts here 
content: -122 
content: 0 
content: 78 
content: 32 
content: -28 
etc... 
.. 
.. 

Teraz, za pomocą prostego testu byte [] Java

String test = "ABC"; 
byte[] message = test.getBytes(); 
public static native void SendMessage(byte[] message, int size); //size = message.length 

C++

static void SendMessage(JNIEnv *env, jclass cls, jbyteArray array, jint array_length) 
{ 
    jbyte* content_array = (env)->GetByteArrayElements(array,NULL); 
    //*env->GetByteArrayRegion(array,0,array_length,content_array); //tried this as well, same results 
    LOGD("content:\n"); 
    for (int i=0; i < array_length; i++) 
    { 
     LOGD("%d",content_array[i]); 
     } 
     (env)->ReleaseByteArrayElements(array,content_array,0); 
    } 

Wyjście

content: 65 //this works perfectly 
content: 66 
content: 67 

Dzięki za pomoc. Bardzo doceniane.

Odpowiedz

1

Jak uzyskać tablicę byte[] w przypadku problemu? Czy to także konwersja z String? Jeśli tak, to zera i wartości ujemne w wynikach dziennika mogą być całkowicie poprawne. Zależy od wprowadzanych znaków i kodowania, którego używasz do konwersji na tablicę bajtów. Jeśli używasz String.getBytes(), tak jak w zwykłym tekście, będziesz używać domyślnego kodowania platformy. Twój prosty przypadek pokazuje, że domyślne kodowanie jest zgodne z ASCII.

+0

Dzięki za odpowiedź. Nie, nie otrzymuję bajtu [] z konwersji String. Bajt [] jest przekazywany z innego źródła. Byłem w stanie przekonwertować go na String po stronie Java do celów rejestracyjnych i zobaczyłem, że zawierał on unikalne znaki. Wspomniałeś o innym kodowaniu. Jak ustawić inne kodowanie z domyślnej platformy? – user2117849

+0

Użyj [String.getBytes (Charset)] (http://docs.oracle.com/javase/7/docs/api/java/lang/String.html#getBytes (java.nio.charset.Charset)). –

1

Nie jestem pewien, co myślisz, że problem jest tutaj. W Javie byte jest typu podpisanego, więc wartość ujemna nie jest nieoczekiwana. Jbyte to prawdopodobnie 8-bitowy podpisany typ C++.

Najbardziej prawdopodobne wyjaśnienia są:

  • To jest jakiś artefakt od sposobu, w jaki tworzysz tablicę bajtów; na przykład zostały zakodowane w UTF-8 (choć zero te wskazują inaczej ...)

  • dotarłeś wartość parametru size prawidłowe:

    • z jakiegoś powodu jest większy niż rozmiar tablicy bajtowej.

    • Proces zapisujący elementy w tablicy bajtów nie spowodował wstawienia size bajtów.


Warto zauważyć, że kod JNI nie sprawdza, że ​​0 <= size < message.length. Jeśli ta metoda zostanie wywołana z argumentem size, który jest poza zakresem, mogą wystąpić złe rzeczy ... w tym błędy segmentacji, które mogą doprowadzić do poważnej awarii maszyny JVM.

+0

dziękuję Stephen za odpowiedź, nie, zrobiłem czek, aby upewnić się, że rozmiar jest poprawny. Jednak nie wspomniałem w moim poście (od czasu edycji), że rzuciłem skonwertowaną tablicę na uint8_t. Czy to może być przyczyną, dla której odbiorca może czytać tylko do momentu wysłania wiadomości do 0? Czy uint8_t obsługuje 0 i wartości ujemne? – user2117849

+0

Wartości dla 'uint8_t' wahają się od 0 do 255. Jednakże, ponieważ jest to rzutowanie w C/C++, * mówisz * kod traktujący wartości w tablicy jako niepodpisane. W każdym razie, w oparciu o aktualizacje, nie sądzę, że problem leży w kodzie, który nam pokazałeś. –