Java Native Interface


Hay ocasiones en las cuales tendremos que trabajar con otro lenguaje a parte de Java en un mismo proyecto y realmente no es mala idea. Pero hay algunas razones en las cuales nos veremos obligados a utilizar otro lenguaje de programación nativo como C/C++.

Entre las razones que destacan para utilizar C/C++ con Java son cuando necesitemos acceder a dispositivos de del sistema, hacerlo con Java es una tarea complicada y en ocasiones imposible, también cuando es necesario maximizar el tiempo de ejecución.

Para llamar a la función nativa, tan solo hay que escribir la palabra native, Ej:

public native String printf(String cadena);

Y para cargar la librería donde se encuentra nuestra función nativa hay que escribir:

static
{
    System.loadLirary("libreria");
}

Nuestro código completo queda de esta forma en el archivo Nativo.java:

public class Nativo
{
    public static native void hola();

    static
    {
        System.loadLibrary("Nativo");
    }
}

Creamos el archivo TestNativo.java donde se encuentra el método main:

public class TestNativo
{
    public static void main(String[] args)
    {
        new Nativo().hola();
    }
}

Una vez que tengamos nuestra clase con funciones nativas, podemos compilar la clase y generar nuestro código en C/C++.

javac Nativo.java
javah -jni Nativo

Se debe generar el archivo de cabecera Nativo.h, y una vez generado, escribimos el código en C.

#include "Nativo.h"

JNIEXPORT void JNICALL Java_Nativo_hola(JNIEnv* env, jclass cl)
{
    printf("Hola desde Cn");
}

El código completo del archivo Nativo.h debe ser el siguiente:

/* DO NOT EDIT THIS FILE - it is machine generated */
#include <jni.h>
/* Header for class Nativo */

#ifndef _Included_Nativo
#define _Included_Nativo
#ifdef __cplusplus
extern "C" {
#endif
/*
 * Class:     Nativo
 * Method:    hola
 * Signature: ()V
 */
JNIEXPORT void JNICALL Java_Nativo_hola
  (JNIEnv *, jclass);

#ifdef __cplusplus
}
#endif
#endif

Y el código del archivo Nativo.c queda de esta forma:

#include "Nativo.h"
#include <stdio.h>
#include <jni.h>

JNIEXPORT void JNICALL Java_Nativo_hola(JNIEnv* env, jclass cl)
{
    printf("Hola desde Cn");
}

Y ahora, compilamos la librería libNativo.so en GNU/Linux. Nota: ya que estamos usando la función printf debemos incluir la cabecera stdio.h.

gcc -fPIC -I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/include
-I/usr/lib/jvm/java-1.6.0-openjdk-1.6.0.0/include/linux -shared -o libNativo.so Nativo.c

Para compilar en Solaris:

cc -G -Ipath/include -Ipath/jdk/solaris -o libNativo.so Nativo.c

Ahora ya podemos ejecutar nuestro programa usando JNI

java -Djava.library.path=. TestNativo
Hola desde C

Posted in

Leave a Reply