Strings Java

Cuando una aplicación Java pasa un string a un programa en lenguaje nativo, le pasa el string como del tipo jstring. Este tipo es muy diferente del tipo string normal del C (Char *). Si nuestro código intenta imprimir directamente un jstring, resultará en una caida de la VM (Máquina Virtual). Por ejemplo, el siguiente segmento de código intenta imprimir incorrectamente un jstring y podría resultar en una caída de la máquina virtual:
/* DO NOT USE jstring THIS WAY !!! */
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
  printf("%s", prompt);

Nuestro método nativo debe utilizar las funciones JNI para convertir los strings Java en strings nativos. El JNI soporta la conversión desde y hacia strings nativos Unicode y UTF-8. En particular, los strings UFT-8 utilizan el bit más alto para señalar caracteres multi-bytes; por lo tanto son compatibles con el ASCII de 7-bits. En Java, los strings UTF-8 siempre terminan en 0.

Acceder a Strings Java

Nuestro método nativo necesita llamar a GetStringUTFChars para imprimir correctamente el string pasado desde la aplicación Java. GetStringUTFChars convierte la representación interna Unicode de un String Java en un string UTF-8. Una vez seguros de que el string sólo contiene caracteres ASCII de 7-bits, se puede pasar directamente a las funciones normales del C, como printf, como se vió en Prompt.c.
JNIEXPORT jstring JNICALL
Java_Prompt_getLine(JNIEnv *env, jobject obj, jstring prompt)
{
  char buf[128];
  const char *str = (*env)->GetStringUTFChars(env, prompt, 0);
  printf("%s", str);
  (*env)->ReleaseStringUTFChars(env, prompt, str);
Observa que cuanto nuestro método nativo haya terminado de utilizar el string UFT-8, debe llamar a ReleaseStringUTFChars. ReleaseStringUTFChars informa a la VM que el método nativo ha terminado con el string, para que pueda liberar la memoria utilizada por el string. Si no llamamos a ReleaseStringUTFChars se nos llenará la memoria.

El método nativo también puede construir un nuevo string utilizando la función NewStringUTF del JNI. Las siguientes líneas de código de Java_Prompt_getLine muestran esto:

  scanf("%s", buf);
  return (*env)->NewStringUTF(env, buf);
}

Utilizar el Puntero a Interface JNIEnv

Los métodos nativos deben acceder y manipular los objetos Java, como los strings, a través del puntero a interface env. En lenguaje C, esto requiere utilizar el puntero env para referenciar la función JNI. Observa cómo el método nativo utiliza el puntero env para referenciar las dos funciones, GetStringUTFChars y ReleaseStringUTFChars. Además, env se pasa como primer párametro a esas funciones.

Otras Funciones JNI para Acceder a Strings Java

El JNI también proporcionar funciones para obtener la representación Unicode de strings Java. Esto es muy útil, por ejemplo, en aquellos sistemas operativos que soportan Unicode como formato nativo. También hay funciones útiles para obtener la longitud de un String Java tanto en UTF-8 como en Unicode.


Ozito