Java-nativer Zugriff - Java Native Access

Java-nativer Zugriff
Originalautor(en) Todd Fast, Timothy Wall, Liang Chen
Erstveröffentlichung 9. Mai 2007 ( 2007-05-09 )
Stabile Version
5.8.0 / 22. März 2021 ; vor 5 Monaten ( 2021-03-22 )
Repository
Geschrieben in C und Java
Betriebssystem Windows, macOS, Android, AIX, FreeBSD, Linux , OpenBSD, Solaris, Windows Mobile
Plattform Java 1.4 oder höher (für JNA 3.5.2 oder früher), Java 1.6 für JNA 4.0.0 und höher
Größe 1,83 MB (archiviert)
Typ Softwarebibliothek
Lizenz LGPL Version 2.1 oder höher und (ab Version 4.0) die Apache Software License, Version 2.0
Webseite github .com /java-native-access /jna

Java Native Access ( JNA ) ist eine von der Community entwickelte Bibliothek, die Java- Programmen einen einfachen Zugriff auf native Shared Libraries ermöglicht, ohne das Java Native Interface (JNI) zu verwenden. Das Design von JNA zielt darauf ab, nativen Zugriff auf natürliche Weise mit minimalem Aufwand zu ermöglichen. Im Gegensatz zu JNI ist kein Boilerplate oder generierter Glue-Code erforderlich.

Die Architektur

Die JNA-Bibliothek verwendet eine kleine native Bibliothek namens Foreign Function Interface Library ( libffi ), um nativen Code dynamisch aufzurufen . Die JNA Bibliothek verwendet native Funktionen Code ermöglicht eine Bibliothek mit dem Namen zu laden und einen abrufen Zeiger auf eine Funktion innerhalb dieser Bibliothek und verwendet libffi Bibliothek es aufzurufen, alle ohne statische Bindungen , Header - Dateien oder jede Kompilierung Phase. Der Entwickler verwendet eine Java-Schnittstelle , um Funktionen und Strukturen in der nativen Zielbibliothek zu beschreiben. Dies macht es ganz einfach, die nativen Plattformfunktionen zu nutzen, ohne den hohen Entwicklungsaufwand für die Konfiguration und Erstellung von JNI- Code zu verursachen.

JNA wurde auf macOS , Microsoft Windows , FreeBSD / OpenBSD , Solaris , Linux , AIX , Windows Mobile und Android entwickelt und getestet . Es ist auch möglich, die nativen Build-Konfigurationen zu optimieren und neu zu kompilieren, damit sie auf den meisten anderen Plattformen, auf denen Java ausgeführt wird, funktioniert.

Zuordnungstypen

Die folgende Tabelle zeigt eine Übersicht über die Typenzuordnung zwischen Java und nativem Code, die von der JNA-Bibliothek unterstützt werden.

Nativer Typ Größe Java-Typ Gängige Windows-Typen
verkohlen 8-Bit-Ganzzahl Byte BYTE, TCHAR
kurz 16-Bit-Ganzzahl kurz WORT
wchar_t 16/32-Bit-Zeichen verkohlen TCHAR
int 32-Bit-Ganzzahl int DWORD
int boolescher Wert boolesch BOOL
lang 32/64-Bit-Ganzzahl EinheimischeLong LANG
lang Lang 64-Bit-Ganzzahl lang __int64
schweben 32-Bit-FP schweben
doppelt 64-Bit-FP doppelt
Zeichen * C-Saite Zeichenfolge LPCSTR
Leere* Zeiger Zeiger LPVOID, GRIFF, LPXXX

Hinweis: Die Bedeutung von TCHAR ändert sich je nach Präprozessordefinitionen zwischen char und wchar_t. LPCTSTR folgt.

Speicherbyte-Ausrichtung für Datenstrukturen

Native Bibliotheken haben keine standardisierte Speicher-Byte-Ausrichtung. JNA verwendet standardmäßig eine betriebssystemplattformspezifische Einstellung, die durch eine bibliotheksspezifische benutzerdefinierte Ausrichtung überschrieben werden kann. Wenn die Alignment-Details in der Dokumentation der nativen Bibliothek nicht angegeben sind, muss das korrekte Alignment während der Implementierung des Java-Wrappers durch Ausprobieren ermittelt werden.

Beispiel

Das folgende Programm lädt die lokale Implementierung der C-Standardbibliothek und verwendet sie, um die Funktion printf aufzurufen .

Hinweis: Der folgende Code ist portabel und funktioniert auf Windows- und POSIX- Plattformen ( GNU + Linux / Unix / macOS ) gleich.

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]);
        }
    }
}

Das folgende Programm lädt die C POSIX-Bibliothek und verwendet sie, um die Standardfunktion mkdir aufzurufen .

Hinweis: Der folgende Code ist portabel und funktioniert auf POSIX- Standardplattformen gleich.

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");
    }
}

Das folgende Programm lädt die Kernel32.dll und verwendet es, um die Beep- und Sleep- Funktionen aufzurufen .

Hinweis: Der folgende Code funktioniert nur auf Windows- Plattformen.

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);
    }
}

Siehe auch

Verweise

Externe Links