El JNI utiliza el tipo jarray para representar referencias a arrays java. Al igual que con jstring, no se puede acceder directamente a los tipos jarray desde el c�digo nativo, se deben utilizar las funciones proporcionadas por el JNI que permiten obtener punteros a los elementos de arrays de enteros.
Nuestro segundo ejemplo, IntArray.java, contiene un m�todo nativo que suma el total de un array de enteros pasado por la aplicaci�n Java. No se puede implementar el m�todo nativo direccionando directamente los elementos del array. El siguiente c�digo intenta incorrectamente acceder directamente a los elementos del array.
/* This program is illegal! */ JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { int i, sum = 0; for (i=0; i<10; i++) sum += arr[i];
La forma correcta de implementar la funci�n anterior, se puede ver en el m�todo nativoIntArray.c. En este ejemplo, se utiliza una funci�n JNI para obtener la longitud del array. Luego se pueden recuperar los elementos. Y finalmente se utiliza una tercera funci�n del JNI para liberar la memoria del array.
�Acceder a un Array de Elementos Primitivos
Primero se obtiene la longitud del array llamando a la funci�n GetArrayLength del JNI. Observa que al contrario que en los array del C, los array Java almacenan informaci�n sobre la longitud.
JNIEXPORT jint JNICALL Java_IntArray_sumArray(JNIEnv *env, jobject obj, jintArray arr) { int i, sum = 0; jsize len = (*env)->GetArrayLength(env, arr);
Luego se obtiene un puntero a los elementos del array. Nuestro ejemplo contiene un array de enteros, por eso utilizamos la funci�n del JNI GetIntArrayElements para obtener este puntero. (El JNI proporciona un juego de funciones para obtener punteros a elementos del array; se utiliza la funci�n que corresponde con el tipo primitivo del array). Una vez obtenido el puntero, se pueden utilizar las operacones normales del C sobre el array de enteros resultante.
jint *body = (*env)->GetIntArrayElements(env, arr, 0); for (i=0; i<len; i++) sum += body[i];
En general, el recolector de basura podr�a eliminar los arrays Java. Sin embargo, la m�quina virtual garantiza que el resultado de GetIntArrayElements apunta a un array de enteros inamovible. El JNI o bien baja el "pin" del array "marc�ndolo" o hace una copia del array en una memoria inamovible. A causa de esto, el c�digo nativo debe llamar a ReleaseIntArrayElements cuando ha terminado de utilizar el array de esta forma.
(*env)->ReleaseIntArrayElements(env, arr, body, 0); return sum; }
ReleaseIntArrayElements permite al JNI copiar de vuelta y liberar la memoria referenciada por el par�metro body si es una copia del array original Java, "desmarca" el array java que fue marcado en la memoria. No olvides llamar a ReleaseIntArrayElements. Si se olvida hacer esta llamada el array permanece marcado por un largo periodo de Tiempo. Y la m�quina virtual no podr� reclamar la memoria utilizada para almacenar la copia inamovible del array.
El JNI proporciona un conjunto de funciones para acceder a los elementos de arrays de los distintos tipos primtivos.
- GetBooleanArrayElements accede a los elementos de un array Java de boolean
- GetByteArrayElements accede a los elementos de un array Java de bytes
- GetCharArrayElements accede a los elementos de un array Java de char
- GetShortArrayElements accede a los elementos de un array Java de short
- GetIntArrayElements accede a los elementos de un array Java de int
- GetLongArrayElements accede a los elementos de un array Java de long
- GetFloatArrayElements accede a los elementos de un array Java de float
- GetDoubleArrayElements accede a los elementos de un array Java de double
�Acceder a un N�mero Peque�o de Elementos
Observa que la funci�n Get<type>ArrayElements potencialmente podr�a copiar el array entero. Podr�amos querer copiar un n�mero limitado de elementos, especialmente si el array es grande. Si s�lo estamos interesados en un n�mero peque�o de elementos (en un array potencialmente grande), deber�amos utilizar las funciones Get/Set<type>ArrayRegion. Estas funciones permiten acceder, mediante copia, a un conjunto peque�o de elementos de un array.
�Acceder a Arrays de Objetos
El JNI proporciona un conjunto separado de funciones para acceder a elementos de arrays de objetos. Se pueden utilizar estas funciones para obtener y seleccionar objetos individuales del array. Observa que no se puede obtener el array de objetos completo de una sola vez.
- GetObjectArrayElement devuelve el objeto del elemento en un �ndice dado.
- SetObjectArrayElement actualiza el objeto del elemento en un �ndice dado.