Cómo llamar código nativo desde Java usando JNI
JNI es la abreviatura de Java Native Interface y el chino es la llamada local de JAVA. A partir de Java 1.1, el estándar Java Native Interface (JNI) pasa a formar parte de la plataforma Java, lo que permite que el código Java interactúe con el código escrito en otros lenguajes. JNI se diseñó originalmente para lenguajes compilados nativos, especialmente C y C, pero no impide el uso de otros lenguajes, siempre que se admita la convención de llamada.
El uso de Java para interactuar con código compilado de forma nativa a menudo resulta en una pérdida de portabilidad de la plataforma. Sin embargo, hay situaciones en las que esto es aceptable o incluso necesario, como usar algunas bibliotecas antiguas, interactuar con hardware o sistemas operativos o mejorar el rendimiento del programa. El estándar JNI al menos garantiza que el código nativo funcionará bajo cualquier implementación de máquina virtual Java.
------------------------------------------- ----- -----------------------
Escribe una clase java con métodos nativos declarados
·Utilice el comando javac para compilar la clase java escrita
·Utilice el nombre de clase java javah?jni para generar un archivo de encabezado con extensión h
·Utilice C/C para implementar métodos locales
·Generar una biblioteca de enlaces dinámicos a partir de archivos escritos en C/C
·ok
1) Escribir un programa java: Aquí tomamos HelloWorld como ejemplo.
Código 1:
clase HolaMundo {
visualización vacía nativa pública HolaMundo()
estática {
; System.loadLibrary("hola");
}
public static void main(String[] args) {
new HelloWorld().displayHelloWorld() ;
}
}
Declarar método nativo: si desea convertir un método en un método nativo, debe declarar el método como nativo y no puede ser realizado. Los parámetros y valores de retorno de los métodos se describen más adelante. Cargar biblioteca dinámica: System.loadLibrary("hello"); cargar la biblioteca dinámica (podemos entenderlo de esta manera: nuestro método displayHelloWorld() no está implementado, pero lo usamos directamente a continuación, por lo que debe inicializarse antes de usarlo) Esto Generalmente se carga en bloques estáticos. Al mismo tiempo, cabe señalar que el parámetro "hola" de System.loadLibrary() es el nombre de la biblioteca dinámica.
2) Compilar
No hay nada que decir javac HelloWorld.java
3) Generar el archivo de encabezado javah con la extensión h?
Contenido del archivo de encabezado jni HelloWorld: /* NO EDITAR ESTE ARCHIVO - es generado por una máquina */
1. incluir
/* Encabezado para la clase HelloWorld */ p>
1. ifndef _Included_HelloWorld
2. define _Included_HelloWorld
3. ifdef __cplusplus
extern "C" {
1. endif
/*
* Clase: HelloWorld
* Método: displayHelloWorld
* Firma: ()V
* /
JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject);
1. ifdef __cplusplus
}
1. endif
2. endif
(Aquí podemos entenderlo de esta manera: este archivo h es equivalente a nuestra interfaz en java, aquí un Java_HelloWorld_displayHelloWorld (JNIEnv *, jobject) es declarado ;método, y luego implementar este método en nuestro método local, lo que significa que el nombre del método que usamos al escribir programas C/C debe ser consistente con el de aquí).
4) Escriba un método local para implementar el método con el mismo nombre que el método declarado en el archivo de encabezado generado por el comando javah.
Código 2:
1 #include "jni.h"
2 #include "HelloWorld.h"
3 // #incluye otros encabezados
4 JNIEXPORT void JNICALL Java_HelloWorld_displayHelloWorld(JNIEnv *env, jobject obj)
{
printf("¡Hola mundo!\n");
return;
}
Tenga en cuenta la primera línea en el código 2, debe agregar jni.h (este archivo se puede encontrar en JAVA_HOME/include). carpeta) se introduce el archivo, porque JNIEnv, jobject y otros tipos en el programa se definen en este archivo de encabezado, además, el archivo de encabezado HelloWorld.h debe introducirse en la línea 2 (así es como lo entiendo: es; equivalente a escribir java Al programar, si desea implementar una interfaz, debe declararla. Aquí, se implementa el método declarado en el archivo de encabezado HelloWorld.h. Por supuesto, este no es necesariamente el caso. Luego guárdelo como HelloWorldImpl.c y estará bien.
5) Generar biblioteca dinámica
Tomando Windows como ejemplo, es necesario generar un archivo dll. En la carpeta donde se guarda HelloWorldImpl.c, use el compilador VC para compilarlo. cl -Ijava_home\include -Ijava_home\include\win32 -LD HelloWorldImp.c -Fehello.dll Nota: El nombre del archivo dll generado se configura después de la opción -Fe, aquí está hola, porque lo usamos al cargar Libary en HelloWorld. archivo java El nombre es hola. Por supuesto, después de modificarlo aquí, también deberá modificarlo allí. Además, debe agregar el parámetro -Ijava_home\include -Ijava_home\include\win32 porque el archivo jni.h se introduce al escribir el método local en el cuarto paso.
6) Ejecute el programa java HelloWorld y estará bien.
----------------------- --- ------------------------------------
El siguiente es un Implementación de ejemplo simple La función de imprimir una oración finalmente se implementa usando printf de C. La interfaz jni generalmente proporcionada a Java incluye un archivo so (que encapsula la implementación de la función c) y un archivo java (la clase que necesita llamar a la ruta).
1. El propósito de JNI es permitir que los métodos Java llamen a algunas funciones implementadas en C. Por ejemplo, la siguiente clase Java necesita llamar a una función local testjni (generalmente declarada como un tipo nativo privado). Primero, el archivo weiqiong.java debe llamarse. se creará con el siguiente contenido:
class weiqiong { static { System.loadLibrary("testjni"); //Carga la biblioteca estática, donde se implementa la función de prueba} private native void testjni(); /Declarar llamada local public void test() { testjni(); public static void main(String args[]) { weiqiong jaja = new weiqiong(); > 2. Luego ejecute javac weiqiong.java. Si no se informa ningún error, se generará un weiqiong.class.
3. Luego configure classpath en su directorio de trabajo actual. Por ejemplo, ingrese directamente la línea de comando: establezca classpath = el directorio completo donde se encuentra weiqiong.class (como c: \ test) y luego ejecute javah weiqiong. se generará, incluida una La declaración de función es la siguiente:
JNIEXPORT void JNICALL Java_weiqiong_testjni (JNIEnv *, jobject
4. Cree el archivo testjni.c para implementar la función anterior. El contenido es el siguiente:
1. incluir
2. incluir
JNIEXPORT void JNICALL Java_weiqiong_testjni (. JNIEnv *env, jobject obj) { printf("jaja---------entra en c!!!\n"); }
5. Para generar el archivo .so, cree el archivo MAKE de la siguiente manera:
libtestjni.so: testjni.o makefile gcc -Wall -rdynamic -shared -o libtestjni.so testjni.o testjni.o: testjni .c weiqiong.h gcc -Wall -c testjni.c -I./ -I/usr/java/j2sdk1.4.0/include -I/usr/java/j2sdk1.4.0/include/linux cl: rm -rf *. o *.so Nota: Hay una pestaña vacía delante de gcc. El directorio de j2sdk se escribe de acuerdo con la versión específica de j2sdk instalada. El nombre del archivo generado debe ser el nombre del parámetro de loadLibrary más "lib".
6. exporte LD_LIBRARY_PATH=., estableciendo así la ruta de la biblioteca al directorio actual, de modo que el archivo java pueda encontrar el archivo so. El enfoque general es copiar el archivo so al directorio LD_LIBRARY_PATH de la máquina local.
7. Ejecute java weiqiong e imprima el resultado: "jaja--------- ¡¡¡entra en c!!!"