Este documento describe el uso de bibliotecas nativas en Java a través de las clases contenedoras. Explica dos enfoques: uno-a-uno y stubs compartidas. También cubre clases de pares que envoltura estructuras de datos nativas y la importancia de liberar la memoria asignada a estas estructuras.
1. ESCUELA
POLITÉCNICA
DEL EJÉRCITO
TECNOLOGÍA
DE SOFTWARE II
LIBRERÍAS
INTEGRANTES: NATIVAS
KATHERINE GARCÉS
JUAN PEÑAFIEL
2. LIBRERÍAS NATIVAS
Una de las aplicaciones de la JNI es escribir métodos nativos
que aprovechan códigos existentes en las bibliotecas nativas.
Los enfoques descritos en este capítulo se exponen
directamente a una librería nativa utilizando métodos
nativos, y por lo tanto tienen la desventaja de hacer una
aplicación que llama tales métodos nativos que dependen
de la biblioteca nativa. Tal solicitud puede ejecutar sólo en un
sistema operativo que suministra la biblioteca nativa. Una
aproximación preferida es declarar independiente del
sistema operativo métodos nativos. Sólo las funciones nativas
la aplicación de esos métodos nativos utilizan las bibliotecas
nativas directamente, limitando la necesidad de portar a las
funciones nativas. La aplicación, incluyendo el declaraciones
de métodos nativos, no necesita ser portado.
3. LIBRERÍAS NATIVAS
9.1 Uno-a-uno
Empecemos con un ejemplo sencillo.
Supongamos que queremos escribir un
contenedor clase que expone la función
atol en la biblioteca estándar de C:
long atol(const char *str);
La función atol analiza una cadena y
devuelve el valor decimal representado por
la cadena.
4. LIBRERÍAS NATIVAS
Definimos una clase contenedora de la
siguiente manera:
public class C {
public static native int atol(String str);
...
}
5. LIBRERÍAS NATIVAS
9.2 Stubs compartidas
El enfoque de uno a uno de mapeo requiere
escribir una función derivada para cada
función nativa que desee ajustar.
Un stub compartido es un método nativo que
se distribuye a otras funciones nativas. La stub
compartido es responsable de convertir los
tipos de argumentos a partir de lo que se
proporciona por la persona que llama lo que
es aceptado por las funciones nativas.
6. LIBRERÍAS NATIVAS
9.3 Uno-a-uno frente a Stubs
compartidas
Uno-a-uno y stubs compartidos son dos
maneras de crear clases contenedoras para
las bibliotecas nativas. Cada uno tiene sus
propias ventajas.
La principal ventaja de stubs compartidos es
que el programador no necesita escribir una
gran número de funciones auxiliares en
código nativo. Una vez que una aplicación
compartida stub tales como CFunction está
disponible, el programador puede ser capaz
de construir envoltura clases sin necesidad de
escribir una sola línea de código nativo.
7. LIBRERÍAS NATIVAS
Stubs compartidas deben usarse con
cuidado, pues los errores en su uso puede
conducir a la memoria dañada y aplicación se
bloquea.
La ventaja de uno-a-uno, es que normalmente
es más eficaz en la conversión de los tipos de
datos que se transfieren entre la máquina
virtual Java y código nativo.
Stubs compartidas, por otro lado, puede
manejar un máximo predeterminado conjunto
de tipos de argumentos y no se puede lograr
un rendimiento óptimo incluso para estos tipos
de argumentos.
8. LIBRERÍAS NATIVAS
9.4 Aplicación de Stubs
compartidas
Describiremos la forma en que se puede
implementar utilizando las funciones
básicas de JNI.
9. LIBRERÍAS NATIVAS
9.4.1 La Clase CPointer
Nos fijamos en la clase CPointer primero porque es
la superclase de ambos CFunction y CMalloc. El
CPointer clase abstracta contiene un campo de
64 bits, los compañeros, que almacena el puntero
subyacente C:
public abstract class CPointer {
protected long peer;
public native void copyIn(int bOff, int[] buf,
int off,int len);
public native void copyOut(...);
...
}
10. LIBRERÍAS NATIVAS
9.4.2 La Clase CMalloc
La clase CMalloc añade dos métodos nativos utilizados
para asignar y liberar memoria C bloques:
public class CMalloc extends CPointer {
private static native long malloc(int size);
public CMalloc(int size) throws OutOfMemoryError {
peer = malloc(size);
if (peer == 0) {
throw new OutOfMemoryError();
}
}
public native void free();
...
}
11. LIBRERÍAS NATIVAS
9.4.3 La Clase CFunction
La implementación de la clase CFunction requiere
el uso de soporte dinámico que une en el sistema
operativo, así como específico de la CPU código
ensamblador. La implementación se presenta a
continuación está dirigida específicamente hacia
el medio ambiente Win32/Intel x86.
Una vez que entienda los principios detrás de la
aplicación de la CFunction clase, puede seguir los
mismos pasos para ponerla en práctica en otras
plataformas. La clase CFunction se define como
sigue:
12. LIBRERÍAS NATIVAS
9.5 Clases de pares
Uno-a-uno y stubs compartidos tienen el problema
de envolver funciones nativas. También se
encontró con el problema de envolver estructuras
de datos nativas en el curso de la construcción de
la aplicación stubs compartida. Recordemos la
definición de la clase CPointer:
public abstract class CPointer {
protected long peer;
public native void copyIn(int bOff, int[] buf,
int off, int len);
public native void copyOut(...);
...
}
13. LIBRERÍAS NATIVAS
Las clases que tienen estructuras de datos
nativas, como CPointer y CMalloc, se llaman clases
de pares. Usted puede construir clases pares para
una variedad de estructuras de datos
nativas, incluyendo, por ejemplo:
• descriptores de fichero
• descriptores de socket
• ventanas u otros gráficos de interfaz de usuario
componentes
14. LIBRERÍAS NATIVAS
9.5.1 Clases de pares en la
Plataforma Java
La corriente de JDK y versiones del SDK de Java 2
(1,1 y 1,2) utilizar las clases de pares internos para
implementar el java.io, java.net y paquetes
java.awt. Una instancia de la java.io.FileDescriptor
clase, por ejemplo, contiene un campo privado
que representa fd un descriptor de fichero nativo:
// Implementation of the java.io.FileDescriptor class
public final class FileDescriptor {
private int fd;
...
}
15. LIBRERÍAS NATIVAS
9.5.2 Estructuras de liberar a
los nativos de Datos
Clases de pares se definen en el lenguaje de programación
Java, por lo que los casos de compañeros las clases serán
basura recogida automáticamente. Usted necesita
asegurarse de que, sin embargo, que las estructuras
subyacentes de datos nativos será liberado también.
Recordemos que la clase contiene un método CMalloc libre
para liberar explícitamente malloc'ed la memoria C:
public class CMalloc extends CPointer {
public native void free();
...
}
16. LIBRERÍAS NATIVAS
9.5.3 Backpointers para
instancias pares
Hemos demostrado que las clases de pares
contienen típicamente un campo privado
que se refiere a la subyacente estructura de
datos original. En algunos casos es deseable
incluir también una referencia de la
estructura de datos nativa de las instancias
de la clase peer. Esto sucede, por
ejemplo, cuando el código nativo tiene que
iniciar devoluciones de llamada a los
métodos de instancia en la clase de pares.