JNI konwertuje jstring na char *


113

Przekazałem ciąg adresu URL z Java do kodu C jako jstringtyp danych za pomocą JNI. A moja metoda biblioteczna wymaga char *as url.

Jak mogę zamienić jstringna char *?

PS: Czy jest jakaś korzyść z używania jcharArray w C? (tj. przekazywanie char []zamiast ciągu znaków w metodzie natywnej)


Czy rozważałeś zapoznanie się z dokumentacją?
Markiz Lorne

Odpowiedzi:


227

Oto kilka przydatnych linków, które znalazłem, kiedy zaczynałem z JNI

http://en.wikipedia.org/wiki/Java_Native_Interface
http://download.oracle.com/javase/1.5.0/docs/guide/jni/spec/functions.html

jeśli chodzi o twój problem, możesz to wykorzystać

JNIEXPORT void JNICALL Java_ClassName_MethodName(JNIEnv *env, jobject obj, jstring javaString)   
{
   const char *nativeString = env->GetStringUTFChars(javaString, 0);

   // use your string

   env->ReleaseStringUTFChars(javaString, nativeString);
}

1
czy trzeba być nativeStringstałym?
Prasham

5
jeśli zaznaczysz drugie łącze, prototyp funkcji GetStringUTFChars to: const jbyte * GetStringUTFChars (JNIEnv * env, jstring string, jboolean * isCopy); więc tak naprawdę nie masz wyboru
Jason Rogers

1
Myślę, że warto zauważyć, że technika opisana tutaj (i na stronie Wikipedii) wykorzystuje zmodyfikowane kodowanie UTF-8, które może nie działać we wszystkich sytuacjach. Zobacz developer.android.com/guide/practices/…
cqcallaw

1
Dzięki, że działa ale co ciekawe const char * nie może zamienić się na char * :).
CoDe

1
@CoDe Technicznie rzecz biorąc, można by to zrobić z pewną magią, ale najlepiej tego unikać; jest to prawdopodobnie zadeklarowane constz jakiegoś powodu. Poprawną odpowiedzią na twój problem jest strcpyprzejście const char*z pliku do pliku char*. To powinno zapewnić zmienność char*, której chcesz.
Loduwijk

51

Najpierw dziękuję za odpowiedź Jasona Rogersa.

W systemie Android && cpp powinno wyglądać tak:

const char *nativeString = env->GetStringUTFChars(javaString, nullptr);

// use your string

env->ReleaseStringUTFChars(javaString, nativeString);

Może naprawić te błędy:

1. błąd: operand bazowy „->” nie ma typu wskaźnikowego „JNIEnv {aka _JNIEnv}”

2. błąd: brak funkcji dopasowującej dla wywołania '_JNIEnv :: GetStringUTFChars (JNIEnv * &, _jstring * &, bool)'

3. błąd: brak funkcji dopasowującej dla wywołania '_JNIEnv :: ReleaseStringUTFChars (JNIEnv * &, _jstring * &, char const * &)'

4.add "env-> DeleteLocalRef (nativeString);" na końcu.


Musisz mieć (* env) -> zamiast env->
AlexanderNajafi

2
Potrzebujesz tylko (*env)->wtedy, gdy używasz C, a nie C ++.
sixones
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.