2014-12-04 11 views
9

Próbuję zamienić C++ std :: string na łańcuch znaków i zwrócę go. Byłoby to łatwe z łatwością, ale z tym, że ciąg, który konwertuję, zawiera prawie losowo wstawione puste znaki. To jest problem dla c_str(), ale nie dla std::string. NewStringUTF będzie przechwytywać tylko część pełnego std::string. Istnieje pewna nadzieja, że ​​std::string ma funkcję length(), która pobiera całą długość, ignorując problematyczne znaki char * \0.C++ std :: string na jstring o ustalonej długości

Istnieje osobna funkcja NewString, która pobiera jchar * i jsize *, więc wygląda obiecująco, ale nie mogę uzyskać std :: string poprawnie skonwertowanego na jchar *. Próbowałem zrobić to tablicy bajtów, ale prawdopodobnie nie robiłem tego dobrze. Miałem dalsze problemy z konwersją int podanej przez length() do jsize, która była wymagana przez wywołanie NewString.

Zrobiłem kawał pracy z vector<char> byteArray(stdString.begin(), stdString.end()), ale to nie doprowadziło mnie bardzo daleko, prawdopodobnie dlatego, że zepsuło to, co jest oryginalnym łańcuchem.

Oto podstawowa funkcja rozrusznika mam, który pracował z ciągów bez zerowych znaków:

jstring StringToJString(JNIEnv * env, const std::string & nativeString) { 
    return env->NewStringUTF(nativeString.c_str()); 
} 

Na marginesie, ta funkcja jest używana wewnątrz pliku otoki JNI dla Zwracanie obiektu std::string.

Dzięki za pomoc lub źródła informacji!

+0

dlaczego twój ciąg ma znaki kończące wartość zerową w środku? Wygląda na to, że używasz niewłaściwego pojemnika do danych. –

+0

Zasadniczo przekształcamy tablicę podwójnych znaków w ciąg znaków, więc sekcje podwójnych bajtów są takie same, jak pusty znak. Nie mogę po prostu wydrukować dubletów i umieścić go jako ciąg ascii, to jest zbyt powolne, i ma białe spacje i inne nie-konieczne rzeczy. –

+3

Struny, zarówno w C++, jak i Java, są przeznaczone do przechowywania rzeczy istotnych dla języka naturalnego. Jeśli chcesz przenieść duble do bufora jakiegoś rodzaju, powinieneś używać 'wektora ' w C++ i 'jbyteArray' po stronie Java. Bez zobowiązań. Używanie 'NewStringUTF' jest szczególnie złe, ponieważ JVM przekształci twój bufor w UTF, myśląc, że przekazujesz mu ciąg znaków. –

Odpowiedz

4

Zrobiłem moje własne rozwiązanie obejścia biorąc porady RedAlert's.

Java teraz oczekuje byte [] z natywnym połączenia:

private native byte[] toString(long thiz); 

Metoda toString teraz nazywa tę metodę wewnątrz niej na std::string:

jbyteArray StringToJByteArray(JNIEnv * env, const std::string &nativeString) { 
    jbyteArray arr = env->NewByteArray(nativeString.length()); 
    env->SetByteArrayRegion(arr,0,nativeString.length(),(jbyte*)nativeString.c_str()); 
    return arr; 
} 

a poziom Java odbiera dane tak:

byte[] byteArray = toString(mNativeInstance); 
String nativeString = ""; 
try { 
    nativeString = new String(byteArray, "UTF-8"); 
} catch (UnsupportedEncodingException e) { 
    Log.e(TAG, "Couldn't convert the jbyteArray to UTF-8"); 
    e.printStackTrace(); 
} 
+2

Dlaczego wciąż używasz ciągów? Nie ma sensu zakodować tablicę podwójną przy użyciu UTF-8 –

+0

Próbowałem przechowywać dane w bazie danych, a nasza poprzednia metoda używała ciągów. Szeregowałam dane wcześniej do base64, ale to było naprawdę powolne, więc teraz biorę dane z surowego bajtu i przenoszę je.Pierwotne pytanie dotyczyło również ciągów, więc utrzymuję odpowiedź istotną dla pytania. –

+0

Twoja baza danych nie może przechowywać danych binarnych? –

Powiązane problemy