Вы находитесь на странице: 1из 79

Integracin Java + C

Introduccin Integracin de Java y C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones

Programacin en Java

Qu es Java?

Un lenguaje de programacin Una tecnologa de desarrollo de aplicaciones


Mquina Virtual (JVM) Librera estndar

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)

JRE = JVM + Libreras


Duke (mascota de Java)

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

IBM y otras empresas tambin tienen JREs

Programacin en Java

Cmo se ejecuta un programa Java?


Java es interpretado? No Java es compilado? No Entonces?

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

Por qu tiene inters...?

Reusar cdigo ya implementado en C o C++ (heredado) en nuevas aplicaciones en Java Acceder a caractersticas del sistema no disponibles en Java

OpenCL, API grfica, gestin de nombres cortos en Windows...

Implementar ciertas partes de la aplicacin en C/C++ por eficiencia

Tratamiento de imgenes, transcodificadores de vdeo...

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

JNA y JNI permiten

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

Java Native Access (JNA)

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/

Java Native Access (JNA)

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

Java Native Access (JNA)

Mapeo de tipos de datos


Native Type Size char 8-bit integer short 16-bit integer 16/32-bit character wchar_t int 32-bit integer int boolean value long 32/64-bit integer long long 64-bit integer float 32-bit FP double 64-bit FP char* C string void* pointer Java Type byte short char int boolean NativeLong long float double String Pointer Common Windows Types BYTE, TCHAR WORD TCHAR DWORD BOOL LONG __int64 LPTCSTR LPVOID, HANDLE, LPXXX

https://jna.dev.java.net/javadoc/overview-summary.html#marshalling

Java Native Access (JNA)

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

Cmo se programa en C/C++?

Hacer una DLL en C con EclipseGavab:

Project > New... C Project > Shared Library > Empty Project ToolChain:

Linux GCC en sistemas Linux MinGW en sistemas Windows

Crear un fichero NativeLib.c que contenga lo siguiente:


#include <stdio.h> void imprimeme(int valor) { printf(El valor es: %d\n, valor); }

Java Native Access

Creamos un fichero native.c que contenga lo siguiente:

Al compilar obtenemos la dll:

Java Native Access

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

Java Native Access

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

Java Native Access

Hay que aadir la librera JNA al build path para que el compilador la pueda encontrar

Java Native Access

En este momento nuestro proyecto Java reconoce la librera y ya podemos utilizarla:

Java Native Access

Para utilizar JNA necesitamos saber:


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:

Java Native Access

Para cada librera se crea una interfaz Java


Normalmente heredar de Library En circunstancias ocasionales, bajo Windows, heredar de StdCallLibrary

Funciones que llevan en la cabecera __stdcall (WINAPI)

Java Native Access

Gestin de la memoria

Reserva hecha en Java


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:

Memory Bfer NIO (New IO)

Reserva hecha en C

Puede usarse en Java Se tiene que liberar desde C

Java Native Access

La interfaz contendr los mtodos que queramos invocar de la librera


Con el mismo nombre Con parmetros de los tipos correspondientes en Java segn la convencin de JNA Con el tipo devuelto correspondiente

Java Native Access

Crear la siguiente interfaz Java en el proyecto Java:

De momento un int de Java nos vale para el argumento de la funcin

Java Native Access

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

Utilizando reflexividad (costoso)

Ejemplos

IntByValue IntByRef IntReturn StringByValue StringByRef StringReturn ArrayByValue ArrayReturn

Ejemplos

StructByRef StructByValue Callback Statefull

Integracin Java + C

Introduccin Integracin de Java + C Java Native Acces (JNA) Java Native Interface (JNI) Conclusiones

Java Native Interface

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

Mejoras 1.4 (NIO) AWT Native Interface

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

Java Native Interface

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

Java Native Interface

Pasos a seguir con JNI

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

Implementar la funcin (NativeLib.c) Generar una librera nativa (NativeLib.dll o libNativeLib.so)

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

Crear un proyecto Java

File New Project > Java > Java Project > Name: JNITest File New Project > C > C Project >

Crear un proyecto C

Name: NativeLib Project Type: Shared library > Empty Project

Proyectos en Eclipse

Configuracin del proyecto C

Incluir los .h necesarios

Project Properties > C/C++ General > Paths and Symbols > Includes > GNU C

Linux /usr/lib/jvm/java-6-sun-1.6.0.10/include/ /usr/lib/jvm/java-6-sun-1.6.0.10/include/linux Windows


C:\Archivos de Programa\Java\jdk1.6.0_10\include C:\Archivos de Programa\Java\jdk1.6.0_10\include\win32

En windows (con Mingw) hay que configurar en el proyecto Java

Project > Properties > C/C++ Build > Settings >


GCC C Compiler > Symbols: _JNI_IMPLEMENTATION_ MinGW C Linker > Miscellaneous: -Wl,--kill-at

Trucos de Eclipse

Configuracin del workspace

Actualizacin automtica del workspace

Window > Preferences > General > Workspace > Refresh automatically

Ejecutar siempre la aplicacin lanzada anteriormente al pulsar el icono

Window > Preferences > Run\Debug > Launching Always launch previous launched application

Configuracin del proyecto C

Compilar al guardar: Project > Properties > C\C++ build> Behaviour > Build on resource save

Ruta de las libreras nativas

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(); } }

Ruta de las libreras nativas

Configuracin externa a la aplicacin Java


Cdigo Java: System.loadLibrary(NativeLib) Variables de Entorno

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

Lnea de Comandos al ejecutar la aplicacin

java -Djava.libray.path=<ruta_lib_nativa> ClaseMain

Configuracin en la aplicacin Java


Windows: System.load(/home/user/ws/LibC/libNativeLib.dll); Linux: System.load(/home/user/ws/LibC/libNativeLib.so);

Ruta de las libreras nativas

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

Generacin del fichero .h

E:\workspace\JNITest\bin>"c:\Archivos de programa\Java\jdk1.6.0_12\bin\javah.exe" -jni -d ..\..\NativeLib NativeLib

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

Arrays de tipos primitivos

Arrays de tipos primitivos

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

Get<Type>ArrayElements / Release<Type>ArrayElements Devuelve la longitud del array

GetArrayLength Crea un array de Java inicializado a sus valores por defecto.


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

jclass intArrCls = (*env)->FindClass(env, "[I"); jobjectArray result = (*env)->NewObjectArray(env, size, intArrCls,NULL);

Ejemplos

ArrayInt ArrayInt2D

Strings

Unicode

GetStringChars \ ReleaseStringChars NewString GetStringRegion \ SetStringRegion GetStringUTFChars \ ReleaseStringUTFChars NewStringUTF GetStringUTFRegion \ SetStringUTFRegion

UTF8*

Existen otras funciones ms avanzadas


*Si el String slo tiene caracteres ASCII el String creado es similar a un *char terminado en \0

Objetos Java

Acceso a atributos

Atributos

GetObjectField / SetObjectField Get<Type>Field / Set<Type>Field

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

Clases: java/lang/String Arrays: [java/lang/String


Z boolean B byte C char S short I int J long F float D double

Tipo Primitivo

Objetos Java

Descriptores de Atributos

"Ljava/lang/String;" "[I" "[Ljava/lang/Object;"

String int[] Object[]

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

jmethodID mid = (*env)->GetStaticMethodID(env, cls, "staticPrintHello", "()V"); (*env)->CallStaticVoidMethod(env, cls, mid);

Objetos Java

Descriptores de Mtodos

"()Ljava/lang/String;" "(ILjava/lang/Class;)J" "([B)V"

String f(); long f(int i, Class c); String(byte[] bytes);

javap -s -p Clase

Ejemplos

CallbackPrintHello CallbackStatic

Objetos Java

Crear objetos (llamada a constructor)

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

Cacheo de referencias a atributos o mtodos

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 */ }

Existen otras tcnicas ms avanzadas (PushLocalFrame, PopLocalFrame)

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

(*env)->IsSameObject(env, obj1, obj2)

Memoria compartida

Buffers con NIO (New Input Output)

Permiten el acceso a memoria nativa directamente desde Java, sin realizar copias Java

ByteBuffer buffer = ByteBuffer.allocateDirect(20) NewDirectByteBuffer GetDirectBufferAddress GetDirectBufferCapacity

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.

La integracin permite acceso a funciones especiales especficas de la plataforma

Вам также может понравиться