Академический Документы
Профессиональный Документы
Культура Документы
Introduccin Integracin de Java y C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones
Programacin en Java
Qu es Java?
Publicado en 1996 por Sun Microsystems El lenguaje de programacin fue diseado por James Gosling
Programacin en Java
Un programa en Java se compila a un cdigo mquina independiente de la plataforma (bytecode) Para ejecutar una aplicacin Java se necesita un entorno de ejecucin de Java (JRE)
Programacin en Java
Sun distribuye un JRE para cada una de las plataformas hardware y sistemas operativos ms importantes Linux, Windows, Solaris... x86, AMD64, Sparc... Apple distribuye un JRE para MacOS X
Programacin en Java
Java utiliza una tecnologa llamada Compilacin JIT (Just In Time) que compila el cdigo bytecode a cdigo mquina de la plataforma En realidad es una transformacin muy rpida porque el bytecode es muy similar al cdigo mquina Existen algunos prototipos de JRE para compilar antes y guardar un formato binario especfico de la plataforma. Compilacin AOT (Ahead Of Time)
Programacin en C/C++
C es un lenguaje de programacin de muy bajo nivel y muy cercano a la mquina Diseado en 1972 por Dennis Ritchie para la programacin de sistemas operativos 1980 Estandarizacin de C ANSI C A mediados de los 80 Bjarne Stroustrup disea C++, versin de C orientada a objetos
Programacin en C/C++
C/C++ son lenguajes de programacin de bajo nivel que se compilan en cdigo mquina especfico de la plataforma y el sistema operativo
Cuando se compila se genera cdigo mquina especfico de la arquitectura (x86, AMD64, PowerPC...) Cuando se enlaza el cdigo compilado se genera un fichero especfico de la arquitectura y del sistema operativo
Programacin en C/C++
Pese a que existen estndares, la realidad es que cada compilador de C/C++ tiene caractersticas especficas
Compilador de Visual Studio (Windows) Compilador GCC (Linux, Windows con MinGW, ...) Compilador de Borland Builder (Windows)
Por lo general existen pequeas incompatibilidades entre estos compiladores que hacen que un cdigo C/C++ no sea independiente del compilador
Reusar cdigo ya implementado en C o C++ (heredado) en nuevas aplicaciones en Java Acceder a caractersticas del sistema no disponibles en Java
Entorno de desarrollo
Parece que todos estamos de acuerdo en que programar con un IDE es ms productivo que programar en el vi o no? Lo ideal es utilizar el mismo entorno para programar el cdigo C/C++ y el cdigo Java (aunque no es necesario) Ejemplos...
EclipseGavab 2.0
Distribucin de Eclipse orientada a la enseanza Incluye todo lo necesario para programar en C/C++, Java, Pascal, ...
Integracin Java + C
Introduccin Integracin de Java + C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones
Integracin Java + C
Diferentes procesos
Llamada a un proceso implementado con C y con comunicacin a travs de la lnea de parmetros y la entrada y salida estndar Comunicacin con un protocolo mediante sockets Java Native Access (JNA) Java Native Interface (JNI)
Mismo proceso
Integracin Java + C
Ventajas Mismo Proceso Muy eficiente la comunicacin Se pueden integrar grficos de forma nativa Si hay errores en la parte en C puede comprometer la estabilidad de la aplicacin Diferentes Procesos La Mquina Virtual de Java no se ve afectada por problemas de estabilidad en la parte nativa La comunicacin es menos eficiente Es necesario implementar un protocolo de serializacin binaria de informacin
Inconvenientes
Integracin de Java + C
Llamar de Java a C y viceversa dentro del mismo proceso JNI permite utilizar una JVM como una librera nativa y ejecutar cdigo Java desde una aplicacin C Problemas y peligros
No hay recoleccin de basura No hay seguridad en la ejecucin del cdigo nativo No hay proteccin frente a violaciones de segmento La aplicacin no es portable (multiplataforma)
Integracin Java + C
JNA
Es una librera Java Permite adaptar en cdigo Java las abstracciones de C (tipos, paso por referencia, memoria...) El cdigo de comunicacin/transformacin se implementa completamente en Java. No hay que implementar cdigo de comunicacin en C. Permite acceder a una librera ya compilada desde Java (ideal para acceso a libreras del sistema)
Integracin Java + C
JNI
Es una librera C Permite adaptar en cdigo C las asbtracciones de Java (objetos, arrays, tipos primitivos, recolector de basura...) El cdigo de comunicacin/transformacin se implementa principalmente en C. Hay que implementar muy poco cdigo de comunicacin en Java.
Integracin Java + C
Introduccin Integracin de Java + C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones
Librera de alto nivel que permite las llamadas a libreras nativas (.dll o .so) ya compiladas No se requiere escribir cdigo C Es una librera relativamente reciente creada para simplificar el acceso a libreras nativas Una llamada a cdigo nativo puede ser hasta 10 veces ms lenta que JNI
https://jna.dev.java.net/
Mapeo automtico de los tipos de datos simples y arrays Se define un interfaz Java con mtodos similares a las funciones de la librera compartida (.dll o .so) Soporta paso por valor y por referencia Licencia LGPL
https://jna.dev.java.net/javadoc/overview-summary.html#marshalling
Vamos a crear una librera C que invocaremos desde Java El programa imprimir por pantalla un nmero entero que recibir como parmetro Project > New... > C Project > Shared Library > Empty Project
Project > New... C Project > Shared Library > Empty Project ToolChain:
Vamos a crear el programa Java que invocar nuestra librera (libNative.dll) El programa Java generar un nmero aleatorio y se lo pasar a la librera para que lo imprima Crear un proyecto Java
File New Project > Java > Java Project > Name: JNATest
En nuestro programa Java tenemos que incluir la librera JNA (jna.jar) Crear una carpeta lib: Importar el fichero jna.jar (Botn derecho sobre la carpeta > Import... > General > File System From directory: el directorio donde est el fichero Seleccionarlo y se copiar a la carpeta lib
Hay que aadir la librera JNA al build path para que el compilador la pueda encontrar
El nombre de la librera El nombre de la funcin, el tipo de valor devuelto y los tipos de los argumentos La funcin se llama imprimeInt El tipo del valor devuelto es void El tipo del argumento es int (un int de C, pero de la conversin se encarga JNA)
En nuestro caso:
Gestin de la memoria
Se puede usar sin problemas en el mtodo nativo No puede utilizarse fuera de la ejecucin del mtodo nativo Para que la librera pueda quedarse con una referencia a la memoria y utilizarla fuera del mtodo nativo:
Reserva hecha en C
Con el mismo nombre Con parmetros de los tipos correspondientes en Java segn la convencin de JNA Con el tipo devuelto correspondiente
Esta interfaz es un recubrimiento de la librera nativa y JNA la utilizar para resolver las llamadas Desde nuestro cdigo Java utilizaremos la interfaz JNA se encarga de resolver las llamadas a la librera nativa
Ejemplos
Ejemplos
Integracin Java + C
Introduccin Integracin de Java + C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones
Libro de referencia
http://java.sun.com/docs/books/jni/ Java(TM) Native Interface: Programmer's Guide and Specification (Java Series) by Sheng Liang 1999
http://java.sun.com/j2se/1.4.2/docs/guide/jni/ jni-14.html
http://java.sun.com/j2se/1.5.0/docs/guide/ awt/1.3/AWT_Native_Interface.html
Tecnologa de comunicacin entre cdigo Java y cdigo nativo en C Disponible desde la versin 1.1 de Java Oficialmente soportada por Sun Compatible con cualquier implementacin de mquina virtual
Crear una clase Java (NativeLib.java) con un mtodo nativo Generar un fichero de cabeceras de C (NativeLib.h) que contiene la cabecera de la funcin en C correspondiente al mtodo nativo en Java C:\>javah -jni NativeLib
Ejemplo
public class NativeLib { NativeLib.java public native void print(); public static void main(String[] args){ System.loadLibrary(C:\ruta_completa\libNativeLib.dll); NativeLib lib = new NativeLib(); lib.print(); } } #include <jni.h> NativeLib.h ... JNIEXPORT void JNICALL Java_NativeLib_print (JNIEnv *, jobject); #include <stdio.h> #include "NativeLib.h" NativeLib.c
JNIEXPORT void JNICALL Java_NativeLib_print(JNIEnv *env, jobject obj) { printf("Hello World!\n"); return; }
Proyectos en Eclipse
Proyectos en Eclipse
File New Project > Java > Java Project > Name: JNITest File New Project > C > C Project >
Crear un proyecto C
Proyectos en Eclipse
Project Properties > C/C++ General > Paths and Symbols > Includes > GNU C
GCC C Compiler > Symbols: _JNI_IMPLEMENTATION_ MinGW C Linker > Miscellaneous: -Wl,--kill-at
Trucos de Eclipse
Window > Preferences > General > Workspace > Refresh automatically
Window > Preferences > Run\Debug > Launching Always launch previous launched application
Compilar al guardar: Project > Properties > C\C++ build> Behaviour > Build on resource save
Carga de librera
NativeLib.java public class NativeLib { public native void print(); public static void main(String[] args){ System.loadLibrary(C:\ruta_completa\libNativeLib.dll); NativeLib lib = new NativeLib(); lib.print(); } }
Linux: La variable de entorno LD_LIBRARY_PATH debe incluir la ruta de la librera Windows: La librera tiene que estar en el directorio de trabajo o en la variable de entorno PATH
Independientemente del mecanismo usado para la carga de la librera nativa Si una librera necesita otra librera, la segunda librera se cargar usando el mecanismo por defecto de la plataforma:
Windows: Directorio de trabajo y variable PATH Linux: Rutas habituales y variable LD_LIBRARY_PATH
Tipos primitivos
Tipos primitivos
Java boolean byte char short int long float double C jboolean jbyte jchar jshort jint jlong jfloat jdouble Precisin Unsigned 8 bits Signed 8 bits Unsigned 16 bits Signed 16 bits Signed 32 bits Signed 64 bits 32 bits 64 bits
Ejemplos
Print IntByValue
Copia entre un array C y un array Java Get<Type>ArrayRegion / Set<Type>ArrayRegion Crea y libera un array C con el contenido del array Java
New<Type>Array
Ejemplo
Prompt
Arrays de Objetos
Arrays de Objetos
Arrays bidimensionales y arrays de Strings GetObjectArrayElement/SetObjectArrayElement No se puede copiar el array completo en C, hay que ir elemento a elemento Array bidimensional
Ejemplos
ArrayInt ArrayInt2D
Strings
Unicode
GetStringChars \ ReleaseStringChars NewString GetStringRegion \ SetStringRegion GetStringUTFChars \ ReleaseStringUTFChars NewStringUTF GetStringUTFRegion \ SetStringUTFRegion
UTF8*
Objetos Java
Acceso a atributos
Atributos
jclass cls = (*env)->GetObjectClass(env, obj); jfieldID fid = (*env)->GetFieldID(env, cls, "s", "Ljava/lang/String;"); jstring jstr = (*env)->GetObjectField(env, obj, fid); const char *str = (*env)->GetStringUTFChars(env, jstr, NULL);
Objetos Java
Class Descriptor
Tipo Primitivo
Objetos Java
Descriptores de Atributos
Ejemplos
AccessField AccessStaticField
Objetos Java
Llamadas a Mtodos
Mtodos de instancia
jclass cls = (*env)->GetObjectClass(env, obj); jmethodID mid = (*env)->GetMethodID(env, cls, "printHello", "()V"); (*env)->CallVoidMethod(env, obj, mid);
Mtodos estticos
Objetos Java
Descriptores de Mtodos
javap -s -p Clase
Ejemplos
CallbackPrintHello CallbackStatic
Objetos Java
jclass dateClass = (*env)->FindClass(env, "java/util/Date"); jmethodID cid = (*env)->GetMethodID(env, dateClass, "<init>", "()V"); jobject result = (*env)->NewObject(env, dateClass, cid); ... (*env)->DeleteLocalRef(env, dateClass);
Ejemplos
CreateDate
Objetos Java
Es mejor cachear el valor del identificador de atributo o mtodo Se puede cachear en la funcin usando una variable static Se puede cachear con un mtodo llamado al cargar la clase (cdigo de inicializacin esttico) de la que se cachean los miembros El cacheo hay que reiniciarle si la clase se descarga y se vuelve a cargar, es decir, si se vuelven a ejecutar los inicializadores estticos
Ejemplo
CreateDatePerformance
Objetos Java
Gestin de memoria
En Java cuando un objeto ya no es referenciado, se libera su memoria automticamente Con JNI existen tres tipos de referencias a objetos:
Local: Referencias a objetos que slo pueden usarse en el contexto de una llamada nativa. No se pueden usar una vez que se ha salido del mtodo. Global: Referencias a objetos que pueden usarse ms all de la llamada a una funcin nativa. Weak: Similares a la WeakReferences de Java
Objetos Java
Referencias Locales
No pueden usarse una vez finalizada la ejecucin de la funcin Una referencia local creada en un hilo no puede usarse en otro hilo Se pueden liberar explcitamente con DeleteLocalRef
Es equivalente a poner una variable a NULL en Java Conviene hacerlo cuando no se use ms el objeto en el mtodo nativo para no esperar a que finalice el mtodo
Objetos Java
Referencias Locales
La mquina virtual slo asegura la creacin de 16 referencias locales Si se necesitan ms se debe llamar a
if ((*env)->EnsureLocalCapacity(env, len)) < 0) { ... /* out of memory */ }
Objetos Java
Referencias Globales
Pueden usarse en mltiples invocaciones de una misma funcin o diferentes funciones Pueden guardarse de forma segura en variables static de las funciones. Pueden guardarse de forma segura en variables del fichero c. Se crean con NewGlobalRef y liberan con DeleteGlobalRef
Objetos Java
Comparar referencias
Memoria compartida
Permiten el acceso a memoria nativa directamente desde Java, sin realizar copias Java
http://java.sun.com/j2se/1.4.2/docs/guide/jni/jni-14.html
Ejemplos
CreateJavaByteBuffer CreateNativeByteBuffer
Opciones ms avanzadas
Excepciones Usar una JVM como una librera en un programa C Hilos de ejecucin Strings no ASCII Asociacin explcita de funciones en C a mtodos nativos en Java Llamadas a la librera JNI usando notacin C++ Dibujar con cdigo nativo (AWT)
Integracin Java + C
Introduccin Tecnologas: JNA y JNI Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones
Conclusiones
Si los datos no son complejos y hay pocas llamadas se puede utilizar la llamada a un proceso pesado Cuando la interaccin es compleja
JNA: No hay muchas llamadas y se dispone de una librera nativa precompilada (JNA puede ser hasta 10 veces menos eficiente que JNI) JNI: Hay muchas llamadas y se tiene experiencia con C.