stringtranslate.com

Acceso nativo de Java

Java Native Access ( JNA ) es una biblioteca desarrollada por la comunidad que proporciona a los programas Java un acceso sencillo a bibliotecas nativas compartidas sin utilizar la interfaz nativa de Java (JNI). El diseño de JNA tiene como objetivo proporcionar acceso nativo de forma natural con un mínimo esfuerzo. A diferencia de JNI, no se requiere código repetitivo ni código de unión generado .

Arquitectura

La biblioteca JNA utiliza una pequeña biblioteca nativa llamada biblioteca de interfaz de función externa ( libffi ) para invocar dinámicamente código nativo . La biblioteca JNA utiliza funciones nativas que permiten al código cargar una biblioteca por nombre y recuperar un puntero a una función dentro de esa biblioteca, y utiliza la biblioteca libffi para invocarla, todo ello sin enlaces estáticos , archivos de encabezado o cualquier fase de compilación. El desarrollador utiliza una interfaz Java para describir funciones y estructuras en la biblioteca nativa de destino. Esto hace que sea bastante fácil aprovechar las características nativas de la plataforma sin incurrir en la alta sobrecarga de desarrollo que supone configurar y crear código JNI .

JNA se ha creado y probado en macOS , Microsoft Windows , FreeBSD / OpenBSD , Solaris , Linux , AIX , Windows Mobile y Android . También es posible modificar y volver a compilar las configuraciones de compilación nativas para que funcione en la mayoría de las demás plataformas que ejecutan Java.

Tipos de mapeo

La siguiente tabla muestra una descripción general de la asignación de tipos entre Java y el código nativo y compatible con la biblioteca JNA. [2]

Nota: El significado de TCHAR cambia entre char y wchar_t según algunas definiciones del preprocesador. A continuación se muestra LPCTSTR .

Alineación de bytes de memoria para estructuras de datos

Las bibliotecas nativas no tienen una alineación de bytes de memoria estandarizada. JNA tiene como opción predeterminada una configuración específica de la plataforma del sistema operativo, que puede ser reemplazada por una alineación personalizada específica de la biblioteca. Si los detalles de la alineación no se proporcionan en la documentación de la biblioteca nativa, la alineación correcta debe determinarse mediante prueba y error durante la implementación del contenedor de Java.

Ejemplo

El siguiente programa carga la implementación de la biblioteca estándar local de C y la utiliza para llamar a la función printf .

Nota: El siguiente código es portable y funciona igual en plataformas Windows y POSIX ( Linux / Unix / MacOS ).

importar com.sun.jna.Library ; importar com.sun.jna.Native ; importar com.sun.jna.Platform ;   /** Ejemplo simple de declaración y uso de una biblioteca nativa. */ public class HelloWorld { public interface CLibrary extends Library { CLibrary INSTANCE = ( CLibrary ) Native . loadLibrary ( ( Platform . isWindows () ? "msvcrt" : "c" ), CLibrary . class ); void printf ( String format , Object ... args ); }                           public static void main ( String [] args ) { CLibrary . INSTANCE . printf ( "Hola, mundo\n" ); for ( int i = 0 ; i < args . length ; i ++ ) { CLibrary . INSTANCE . printf ( "Argumento %d: %s\n" , i , args [ i ] ); } } }                     

El siguiente programa carga la biblioteca C POSIX y la utiliza para llamar a la función estándar mkdir .

Nota: El siguiente código es portable y funciona igual en las plataformas de estándares POSIX .

importar com.sun.jna.Library ; importar com.sun.jna.Native ;  /** Ejemplo simple de declaración y uso de biblioteca POSIX nativa de C. */ public class ExampleOfPOSIX { public interface POSIX extends Library { public int chmod ( String nombre_archivo , int modo ); public int chown ( String nombre_archivo , int usuario , int grupo ); public int rename ( String ruta_anterior , String ruta_nueva ); public int kill ( int pid , int señal ); public int link ( String ruta_anterior , String ruta_nueva ); public int mkdir ( String ruta , int modo ); public int rmdir ( String ruta ); }                                                     public static void main ( String [] args ) { // Es posible cargar msvcrt para su soporte parcial de POSIX en Windows... POSIX posix = ( POSIX ) Native.loadLibrary ( "c" , POSIX.class ); // pero seguirá fallando en Windows debido a que falta /tmp. posix.mkdir ( " /tmp / newdir" , 0777 ); posix.rename ( " / tmp /newdir" , " / tmp / renamedir" ); } }                 

El programa a continuación carga Kernel32.dll y lo utiliza para llamar a las funciones Beep y Sleep .

Nota: El siguiente código solo funciona en plataformas Windows .

importar com.sun.jna.Library ; importar com.sun.jna.Native ;  /** Ejemplo simple de declaración y uso de una biblioteca nativa de Windows. */ public class BeepExample { public interface Kernel32 extends Library { // LA FRECUENCIA se expresa en hercios y varía de 37 a 32767 // LA DURACIÓN se expresa en milisegundos public boolean Beep ( int FREQUENCY , int DURATION ); public void Sleep ( int DURATION ); }                       public static void main ( String [ ] args ) { Kernel32 lib = ( Kernel32 ) Native.loadLibrary ( " kernel32 " , Kernel32.class ) ; lib.Beep ( 698,500 ) ; lib.Sleep ( 500 ) ; lib.Beep ( 698,500 ) ; } }                 

Actuación

Los puntos de referencia muestran que el promedio de JNA es diez veces más lento que el de JNI. [3] [4] [5]

Alternativas

Están surgiendo varias alternativas. [6] Al evaluar estas herramientas de desarrollo de software, se debe tener en cuenta el equilibrio entre la facilidad de implementación del código y la velocidad de ejecución. La adición de bibliotecas dependientes de terceros que deben redistribuirse y actualizarse es otro factor a tener en cuenta a la hora de decidir qué herramienta utilizar. También se debe considerar el nivel de preparación tecnológica .

Véase también

Referencias

  1. ^ "Versión 5.14.0". GitHub . 14 de enero de 2023.
  2. ^ "Asignaciones de tipos predeterminadas". jna.dev.java.net . Consultado el 2 de agosto de 2011 .
  3. ^ "Rendimiento de JNI vs JNA". Reddit . Consultado el 30 de marzo de 2023 .
  4. ^ "Punto de referencia JNI vs JNA". Medium . Consultado el 30 de marzo de 2023 .
  5. ^ "Punto de referencia de rendimiento de JNI vs JNA". Desbordamiento de pila . Desbordamiento de pila . Consultado el 30 de marzo de 2023 .
  6. ^ "Están surgiendo alternativas a la JNI". OKTA . Consultado el 30 de marzo de 2023 .

Enlaces externos