Acceso nativo de Java - Java Native Access

Acceso nativo de Java
Autor (es) original (es) Todd Fast, Timothy Wall, Liang Chen
Versión inicial 9 de mayo de 2007 ( 2007-05-09 )
Lanzamiento estable
5.8.0 / 22 de marzo de 2021 ; hace 5 meses ( 2021-03-22 )
Repositorio
Escrito en C y Java
Sistema operativo Windows, macOS, Android, AIX, FreeBSD, Linux , OpenBSD, Solaris, Windows Mobile
Plataforma Java 1.4 o posterior (para JNA 3.5.2 o anterior), Java 1.6 para JNA 4.0.0 y posterior
Tamaño 1,83 MB (archivado)
Escribe Biblioteca de software
Licencia LGPL versión 2.1 o posterior y (desde la versión 4.0 en adelante) la licencia de software Apache, versión 2.0
Sitio web github .com / java-native-access / jna

Java Native Access ( JNA ) es una biblioteca desarrollada por la comunidad que proporciona a los programas Java un fácil acceso a las bibliotecas compartidas nativas 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 de esfuerzo. A diferencia de JNI, no se requiere un código repetitivo ni un código de pegamento generado .

Arquitectura

La biblioteca JNA utiliza una pequeña biblioteca nativa llamada biblioteca de interfaz de función externa ( libffi ) para invocar dinámicamente el código nativo . La biblioteca JNA usa funciones nativas que permiten que el código cargue una biblioteca por nombre y recupere un puntero a una función dentro de esa biblioteca, y usa la biblioteca libffi para invocarla, todo 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 de la plataforma nativa sin incurrir en la alta sobrecarga de desarrollo de configurar y compilar código JNI .

JNA está construido y probado en macOS , Microsoft Windows , FreeBSD / OpenBSD , Solaris , Linux , AIX , Windows Mobile y Android . También es posible modificar y recompilar las configuraciones de compilación nativas para que funcione en la mayoría de las otras plataformas que ejecutan Java.

Tipos de mapeo

La siguiente tabla muestra una descripción general del mapeo de tipos entre Java y código nativo y el soporte de la biblioteca JNA.

Tipo nativo Tamaño Tipo de Java Tipos comunes de Windows
carbonizarse Entero de 8 bits byte BYTE, TCHAR
pequeño Entero de 16 bits pequeño PALABRA
wchar_t Carácter de 16/32 bits carbonizarse TCHAR
En t Entero de 32 bits En t DWORD
En t valor booleano booleano BOOL
largo Entero de 32/64 bits NativoLargo LARGO
largo largo Entero de 64 bits largo __int64
flotador FP de 32 bits flotador
doble FP de 64 bits doble
char * cuerda C Cuerda LPCSTR
vacío* puntero Puntero LPVOID, MANIJA, LPXXX

Nota: El significado de TCHAR cambia entre char y wchar_t de acuerdo con algunas definiciones de preprocesador. Sigue LPCTSTR.

Alineación de bytes de memoria para estructuras de datos

Las bibliotecas nativas no tienen ningún tipo de alineación de bytes de memoria estandarizada. JNA utiliza de forma predeterminada una configuración específica de la plataforma del sistema operativo, que puede ser anulada 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 usa para llamar a la función printf .

Nota: El siguiente código es portátil y funciona igual en plataformas Windows y POSIX ( GNU + Linux / Unix / macOS ).

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Platform;

/** Simple example of native library declaration and usage. */
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("Hello, World\n");
        for (int i = 0; i < args.length; i++) {
            CLibrary.INSTANCE.printf("Argument %d: %s\n", i, args[i]);
        }
    }
}

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

Nota: El siguiente código es portátil y funciona igual en plataformas estándar POSIX .

import com.sun.jna.Library;
import com.sun.jna.Native;

/** Simple example of native C POSIX library declaration and usage. */
public class ExampleOfPOSIX {
    public interface POSIX extends Library {
	    public int chmod(String filename, int mode);
	    public int chown(String filename, int user, int group);
	    public int rename(String oldpath, String newpath);
	    public int kill(int pid, int signal);
	    public int link(String oldpath, String newpath);
	    public int mkdir(String path, int mode);
	    public int rmdir(String path);
    }

    public static void main(String[] args) {
        // It is possible to load msvcrt for its partial POSIX support on Windows...
        POSIX posix = (POSIX) Native.loadLibrary("c", POSIX.class);
        // but it will still fail on Windows due to /tmp being missing.
	    posix.mkdir("/tmp/newdir", 0777);
	    posix.rename("/tmp/newdir","/tmp/renamedir");
    }
}

El siguiente programa carga Kernel32.dll y lo usa para llamar a las funciones Beep y Sleep .

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

import com.sun.jna.Library;
import com.sun.jna.Native;

/** Simple example of Windows native library declaration and usage. */
public class BeepExample {
    public interface Kernel32 extends Library {
        // FREQUENCY is expressed in hertz and ranges from 37 to 32767
        // DURATION is expressed in milliseconds
        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);
    }
}

Ver también

Referencias

enlaces externos