JNI convirtiendo jstring a char *

113

He pasado una cadena de URL de Java al código C como jstringtipo de datos mediante el uso de JNI. Y mi método de biblioteca necesita una char *url.

¿Cómo puedo convertir jstringen char *?

PD: ¿Hay alguna ventaja de usar jcharArray en C? (es decir, pasar en char []lugar de cadena en el método nativo)

Prasham
fuente
¿Ha pensado en consultar la documentación?
Marqués de Lorne

Respuestas:

227

Aquí hay un par de enlaces útiles que encontré cuando comencé con JNI

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

con respecto a su problema, puede utilizar este

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);
}
Jason Rogers
fuente
1
¿Es necesario mantenerlo nativeStringconstante?
Prasham
5
si marca el segundo enlace, el prototipo de la función GetStringUTFChars es: const jbyte * GetStringUTFChars (JNIEnv * env, jstring string, jboolean * isCopy); así que realmente no tienes otra opción
Jason Rogers
1
Creo que vale la pena señalar que la técnica descrita aquí (y en la página de Wikipedia) utiliza codificación UTF-8 modificada, que puede no funcionar en todas las situaciones. Ver developer.android.com/guide/practices/…
cqcallaw
1
Gracias, ese trabajo pero curiosamente const char * no se puede convertir en char * :).
Código
1
@CoDe Técnicamente, podría hacerlo con algo de magia, pero es mejor evitarlo; probablemente se declara constpor una razón. La respuesta correcta a su problema es strcpyde const char*a char*. Eso debería proporcionarle el mutable char*que desea.
Loduwijk
51

Gracias primero la respuesta de Jason Rogers.

En Android && cpp debería ser esto:

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

// use your string

env->ReleaseStringUTFChars(javaString, nativeString);

Puede corregir estos errores:

1.error: el operando base de '->' tiene un tipo sin puntero 'JNIEnv {también conocido como _JNIEnv}'

2.error: no hay función coincidente para la llamada a '_JNIEnv :: GetStringUTFChars (JNIEnv * &, _jstring * &, bool)'

3.error: no hay función coincidente para la llamada a '_JNIEnv :: ReleaseStringUTFChars (JNIEnv * &, _jstring * &, char const * &)'

4.add "env-> DeleteLocalRef (nativeString);" al final.

Kangear
fuente
Necesita tener (* env) -> en lugar de env->
AlexanderNajafi
2
Solo lo necesita (*env)->si está usando C, no C ++.
sixones