Instalación de Cygwin.
El primer paso es descargar el Cygwin con el paquete "devel", luego de esto
ejecute el Cygwin Bash Shell, y verifique que estén instaladas las siguientes herramientas:
Herramienta
| Comando en Cygwin Bash Shell
|
| Cygwin 1.5.x | cygcheck -c cygwin |
| Cygwin gcc-core (C compiler) 3.4.x | gcc --version
|
| Cygwin gcc-c++ (C++ compiler) 3.4.x | g++ --version |
| Cygwin gdb (GNU Debugger) 6.5.50 | gdb --version
|
| Cygwin make 3.80 | make --version |
Ahora se agrega en la variable de entorno patch, el directorio de instalación de Cygwin, siguiendo los siguientes pasos:
De click en Inicio, ubique el icono Mi PC y de click derecho sobre él, seguidamente seleccione propiedades. Aparecerá la ventana de propiedades del sistema seleccione la pestaña Opciones Avanzadas, luego de click en variables de entorno, busque la variable path y adicione al final de la linea y despúes de ; la ruta de la carpeta bin de Cygwin, como se muestra en la siguiente gráfica.
Creación y configuración del proyecto JAVA.
Seleccione File/New Project. En Choose Project, seleccione Categories:java seguido de Java Application, luego de click en el botón next.
Seguido de esto aparecerá la ventana New Java Application. En el campo project name escriba HelloWorldNative, seleccione un folder para el proyecto.
Luego de click derecho en el nodo del projecto edite la clase main como sigue:
Úbiquese en el nodo principal del proyecto, de click derecho y seleccione Clean and Build
la clase deberá compilar sin errores.
Creación del archivo de cabecera.
Diríjase a la consola y úbiquese en el directorio del proyecto. escriba:
<JAVA_HOME>\bin\javah.exe -o HelloWorldNative.h -jni
-classpath <PROJECTS_ROOT>\HelloWorldNative\build\classes helloworld.Main
reemplazando <JAVA_HOME> por la respectiva ruta donde se encuentra instalado el JDK, y reemplazando <PROJECTS_ROOT>, por la ruta respectiva del proyecto. A modo de ejemplo observe la siguiente gráfica.
Después de la ejecución del anterior comando el archivo HelloWorldNative. h es generado. Este es requerido para la declaración del metodo nativo.
Creación y configuración del proyeto DLL en C/C++Seleccione File/New Proyect. En Choose Project, seleccione Categories:C/C++ seguido de C/C++ Dynamic Library, luego de click en el botón next. Observese la siquiente gráfica.
Seguidamente aparecerá la ventana
NewC/C++ Dynamic Library, escriba en el campo
Project Name HelloWorldC.
En project Location escriba la ruta de localización del proyecto java realizado anteriormete.
De click derecho en el nodo del proyecto
HelloWorldC, seleccione propiedades, expanda el nodo
Build y agregue los directorios
include e
include/win32 del JDK en el campo
Include Directorires, para los sub nodos
C Compiler y
C++ Compiler. Agrege el siguiente comando en
Command Line /Additional Options: ![]()
-mno-cygwin -Wl,--add-stdcall-alias -shared -m32.
La opción
-mno-cygwin option, habilita la no dependencia de las librerias de Cygwin para la construccion de los dlls, es decir la dlls podrán funcionar en maquinas que no tengan instalado Cygwin,
-
Wl,--add-stdcall-alias, pasa la opcion
--add-stdcall- a el enlazador (
linker) ; Sin esto se producirá una falla en tiempo de compilación de tipo UnsatisfiedLinkError.
El
-shared option, le dice al compilador que genere una dll, y no un archivo ejecutable.
-m32, le indica al compilador que compile a 32bit.
Observe las siguinte gráfica a modo de ejemplo.
De click sobre el sub menu
Linker, escriba en
General/Output la ruta
dist/DLL/libHelloWorldC.dl.
Agregando archivo de cabecera al proyecto DLL en C/C++.
Copie el archivo de HelloWorldNative.h ubicado en el fólder de localización de projectos a el projecto en C. para el ejemplo seria copiar
C:\JNIDemo\HelloWorldNative.h al fólder C:\JNIDemo\HelloWorldC\
HelloWorldNative.h.Expanda el projecto
HelloWorldC y de click derecho en
ResourceFiles, seleccione A
dd Existing Item y agregue el archivo
C:\JNIDemo\HelloWorldNative.h.
Implementado el archivo
HelloWorldNative.c.
De click derecho sobre el nodo principal del proyecto
HelloWorldC, úbiquese en el subnodo
Source Files de click derecho sobre este y seleccione
New Empty C File, en el campo
File Name escriba
HelloWorldNative, se creará un archivo llamado
HelloWorldNative.c, editelo con las siguientes lineas:
#include <jni.h>
#include <stdio.h>
#include "HelloWorldNative.h"
JNIEXPORT void JNICALL Java_helloworldnative_Main_nativePrint (JNIEnv *env, jobject obj){
printf("\nHello World from C\n");
}
Luego de click derecho en sobre el nodo principal del proyecto y seleccione
Build, el proyecto debe compilar sin errores.
A modo de ejemplo se muestran las siguientes gráficas.
El resultado de la anterior ejecución es el archivo
C:\JNIDemo\HelloWorldC\dist\DLL\libHelloWorldC.dll.
Construyendo y ejecutando la aplicación en conjunto.Abra el Main.java y el siguinte bloque de inicializacion static que asegura la carga de la dll construida en el anterior paso.
static {
System.load("C:\\JNIDemo\\HelloWorldC\\dist\\DLL\\libHelloWorldC.dll");
}
Finalmente construya el proyecto y ejecútelo, dando click derecho sobre el nodo HelloWorldNative, selecione
Build, de click derecho sobre la clase main y seleccione Run "Main.java". La ejecución mostrará Hello World from C. Observe a manera de guia la siguiente gráfica.
NOTAS
DLL Dynamic Link Librarary, son archivos con código ejecutable generalmente construidos en C. que se cargan bajo demanda del programa por parte del sistema operativo. Especificamente esta denominación hace referencia a los sistemas operativos Windows, aunque el concepto existe en practicamente totos los sistemas operativos, por ejemplo para linux y open solaris la denominación es OS ():
#ifdef y
#ifndef son directivas condicionales especializadas para comprobar si un macro-identificador está
definido o no.
extern Modificador utilizado para declarar un método que se
implementa externamente.
Usage: javah [options] <classes>
where [options] include:
-help Print this help message and exit
-classpath <path> Path from which to load classes
-bootclasspath <path> Path from which to load bootstrap classes
-d <dir> Output directory
-o <file> Output file (only one of -d or -o may be used)
-jni Generate JNI-style header file (default)
-version Print version information
-verbose Enable verbose output
-force Always write output files
<classes> are specified with their fully qualified names (for
instance, java.lang.Object).