2014-12-04 18 views
9

Sto provando a trasformare una stringa C++ in una stringa jstring e restituirla. Questo sarebbe abbastanza facile conC++ std :: string a jstring con una lunghezza fissa

JNIEnv*->NewStringUTF(stdString.c_str()) 

ma il problema è che la stringa sto convertendo ha intervallati quasi casualmente caratteri null in esso. Questo è un problema per lo c_str(), ma non lo std::string. NewStringUTF prenderà solo una porzione dell'intero std::string. C'è un po 'di speranza in quanto il std::string ha una funzione length(), che ottiene l'intera lunghezza, ignorando il carattere problematico * \0 caratteri.

C'è una funzione separata NewString che accetta un jchar * e un jsize *, quindi sembra promettente, ma non riesco a ottenere lo std :: string convertito correttamente in jchar *. Ho provato a renderlo un array di byte, ma probabilmente non lo stavo facendo bene. Ho avuto ulteriori problemi a convertire l'int data dallo length() in un jsize, che era richiesto dalla chiamata NewString.

Ho svolto un po 'di lavoro con vector<char> byteArray(stdString.begin(), stdString.end()), ma questo non mi ha portato molto lontano, probabilmente perché questo è incasinare quello che è la stringa originale.

Ecco la funzione di base di avviamento che ho, che ha lavorato con le stringhe senza caratteri nulli:

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

Come nota a margine, questa funzione viene utilizzata all'interno di un file wrapper di JNI per la restituzione di std::string un oggetto.

Grazie per qualsiasi aiuto o fonte di informazioni!

+0

perché la stringa ha caratteri di terminazione null nel mezzo? Sembra che tu stia usando il contenitore sbagliato per i tuoi dati. –

+0

Stiamo essenzialmente trasformando una serie di doppi in una stringa, quindi le sezioni dei doppi byte sono le stesse del carattere null. Non posso semplicemente stampare il doppio e metterlo come una stringa ascii, troppo lento, e ha spazi bianchi e altre cose non necessarie. –

+3

Le stringhe, sia in C++ che in Java, sono pensate per memorizzare elementi pertinenti al linguaggio naturale. Se hai bisogno di spostare i duplicati in un buffer di qualche tipo, dovresti usare un 'vector ' in C++ e 'jbyteArray' sul lato Java. Senza archi L'utilizzo di 'NewStringUTF' è particolarmente negativo, poiché la JVM trasformerà il tuo buffer in UTF, pensando di passargli una stringa. –

risposta

4

Ho realizzato la mia soluzione alternativa seguendo i consigli di RedAlert.

Java si aspetta ora un byte [] dalla chiamata nativa:

private native byte[] toString(long thiz); 

Il metodo toString ora chiama questo metodo al suo interno su un 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; 
} 

E il livello Java riceve i dati In questo modo:

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

Perché stai ancora usando le stringhe? Non ha molto senso codificare una matrice di doppi usando UTF-8 –

+0

Stavo cercando di memorizzare i dati in un database e il nostro metodo precedente usava le stringhe. Stavo serializzando i dati in precedenza in base64, ma era molto lento, quindi ora sto solo prendendo i dati grezzi dei byte e spostandoli.La domanda originale riguardava anche le stringhe, quindi sto mantenendo la risposta pertinente alla domanda. –

+0

Il database non è in grado di memorizzare dati binari? –

Problemi correlati