Este capítulo está siendo desarrollado, puede contener errores.
Java provee la posibilidad de acceder a funciones desarrolladas en C a través de lo que se llama "métodos nativos". Actualmente existen dos tecnologías a través de las cuales podemos invocar funciones C desde nuestros programas Java. Estas son:
- JNI - "Java Native Interface" (la tecnología tradicional), y
- JNA - "Java Native Access"
En este capítulo desarrollaremos algunos ejemplos en ambas tecnologías con los objetivos de comprender como se utilizan y de poderlas comparar.
HolaMundo - JNI
Usar JNI es algo engorroso. A continuación voy a enumerar los pasos que hay que realizar para invocar a una función C que imprima "Hola Mundo" en la consola.
Si el lector considera que este ejemplo es demasiado complicado o se le complica seguirlo hasta el final le recomiendo que vaya directamente a ver la implementación desarrollada con JNA expuesta más abajo.
1 - Definir una clase Java con los métodos nativos
CLib.java (clase con métodos nativos)
1:
2:package demo.jni;
3:
4:public class CLib
5:{
6: // los metodos nativos no se desarrollan
7: public native void holaMundo();
8:}
9:
2 - Compilar el .java anterior y luego correr el comando javah para generar el .h con los headers C que se corresponden con los métodos nativos definidos en la clase.
javah -jni demo.jni.CLib
Debemos tener en cuenta que para ejecutar este comando desde la línea de comandos tenemos que tener seteado el PATH a %JAVA_HOME%\bin y debemos estar posicionados en el directorio padre del paquete demo o bien debemos tener seteado correctamente el CLASSPATH.
El comando javah debe generar el siguiente archivo:
demo_jni_CLib.h
1:/* DO NOT EDIT THIS FILE - it is machine generated */
2:#include <jni.h>
3:/* Header for class demo_jni_CLib */
4:
5:#ifndef _Included_demo_jni_CLib
6:#define _Included_demo_jni_CLib
7:#ifdef __cplusplus
8:extern "C" {
9:#endif
10:/*
11: * Class: demo_jni_CLib
12: * Method: holaMundo
13: * Signature: ()V
14: */
15:JNIEXPORT void JNICALL Java_demo_jni_CLib_holaMundo
16: (JNIEnv *, jobject);
17:
18:#ifdef __cplusplus
19:}
20:#endif
21:#endif
22:
3 - Programar en C la implementación del método nativo holaMundo utilizando el header que obtuvimos luego de correr el comando javah.
demoJNI.c
1:
2:#include<stdio.h>
3:#include<jni.h>
4:#include "demo_jni_CLib.h"
5:
6:JNIEXPORT void JNICALL Java_demo_jni_CLib_holaMundo (JNIEnv *env, jobject obj)
7:{
8: printf("Hola Mundo\n");
9:}
10:
4 - Compilar el código C y generar una DLL. Si usamos MinWG el comando será el siguiente:
gcc -c -I%JAVA_HOME\include -I%JAVA_HOME%\include\win32 demoJNI.c
gcc -shared -o demoJNI.dll demoJNI.o
Esto generara el archivo demoJNI.dll.
5 - Escribir un programa que instancie la clase CLib e invoque al método holaMundo.
Demo.java
1:
2:package demo.jni;
3:
4:public class Demo
5:{
6: public static void main(String[] args)
7: {
8: System.loadLibrary("demoJNI");
9: CLib clib = new CLib();
10: clib.holaMundo();
11: }
12:}
13:
Más información en: http://java.sun.com/docs/books/jni/html/start.html
Hola Mundo - JNA
El enfoque que provee JNA es mucho más intuitivo, simple y directo. Solo necesitamos descargar el archivo jna.jar.
1 - En JNA comenzamos por escribir el código C sin condicionarlo con ningún header extraño.
demoJNA.c
1:
2:#include <stdio.h>
3:void holaMundo()
4:{
5: printf("Hola Mundo\n");
6:}
7:
2 - El siguiente paso es crear una interface Java que defina el método holaMundo que "wrappea" a la función escrita en C.
CLib.java
1:
2:package demo.jna;
3:
4:import com.sun.jna.Library;
5:
6:public interface CLib extends Library
7:{
8: public void holaMundo();
9:}
10:
3 - Por último podemos escribir el programa principal que invoca al método holaMundo de la interface CLib.
Demo.java
1:
2:package demo.jna;
3:
4:import com.sun.jna.Native;
5:
6:public class Demo
7:{
8: public static void main(String[] args)
9: {
10: CLib clib= (CLib) Native.loadLibrary("demoJNA", CLib.class);
11: clib.holaMundo();
12: }
13:}
14:
Más información en: https://jna.dev.java.net/
.