Article de reference

Accès natif Java

{{cite web | url=https://github.com/java-native-access/jna/releases/tag/5.17.0 | title=Release 5.17.0 | website=[[GitHub]] | date=2025-03-16}} "},"latest preview version":{"wt":...

Java d'accéder facilement aux bibliothèques partagées natives sans utiliser l' interface JNI ( Java Native Interface ). JNA a été conçue pour offrir un accès natif naturel et simple. Contrairement à JNI, elle ne nécessite aucun code répétitif ni code d'interface généré automatiquement.

Depuis Java 22, l' API Foreign Function and Memory est proposée comme alternative moderne standard.

libffi ( Foreign Function Interface Library ) pour invoquer dynamiquement du code natif . Grâce à des fonctions natives, le code peut charger une bibliothèque par son nom et récupérer un pointeur vers une fonction de cette bibliothèque. L'appel de cette fonction se fait ensuite via libffi , le tout sans liaison statique , sans fichier d'en-tête ni compilation. Le développeur utilise une interface Java pour décrire les fonctions et les structures de la bibliothèque native cible. Il est ainsi très facile de tirer parti des fonctionnalités natives de la plateforme sans les lourdes contraintes de développement liées à la configuration et à la compilation de code JNI .

JNA est compilé et testé sur macOS , Microsoft Windows , FreeBSD / OpenBSD , Solaris , Linux , AIX , Windows Mobile et Android . Il est également possible d'adapter et de recompiler les configurations de compilation natives pour le rendre compatible avec la plupart des autres plateformes exécutant Java.

Types de cartographie

Le tableau suivant présente un aperçu des correspondances entre le code Java et le code natif et prises en charge par la bibliothèque JNA.

log.js:15 (Glean.core.Upload.PingUploadManager) Ping dd94da72-e022-48a6-b06f-47b816267447 envoyé avec succès 200. `

Type natif Taille Type Java Types de Windows courants
char,int8_tEntier 8 bits byteBYTE,TCHAR
short,int16_tEntier 16 bits shortWORD
wchar_t,char16_tCaractère 16/32 bits charTCHAR
int,int32_tentier 32 bits intDWORD
int,boolvaleur booléenne booleanBOOL
longentier 32/64 bits com.sun.jna.NativeLongLONG
long long,int64_tentier 64 bits long__int64
float,float32_tFacteur de puissance 32 bits float
double,float64_tFacteur de puissance 64 bits double
char*corde de do java.lang.StringLPCSTR
void*Aiguille com.sun.jna.PointerLPVOID, HANDLE,LPXXX

Remarque : La signification de TCHARchange entre charet wchar_tselon certaines définitions de préprocesseur. LPCTSTRsuit.(Glean.core.Upload.PingUploadManager) Ping c7046691-561b-451e-ad68-3df489dc396d envoyé avec succès 200. log.js:15 (Glean.core.Upload.PingUploadManager) Ping dd94da72-e022-48a6-b06f-47b816267447 envoyé avec succès 200.

(Glean.core.Upload.PingUploadManager) Ping c7046691-561b-451e-ad68-3df489dc396d envoyé avec succès 200. log.js:15 (Glean.core.Upload.PingUploadManager) Ping dd94da72-e022-48a6-b06f-47b816267447 envoyé avec succès 200.

Alignement des octets en mémoire pour les structures de données

Les bibliothèques natives n'ont pas de format d'alignement mémoire standardisé. JNA utilise par défaut un paramètre spécifique à la plateforme système, qui peut être remplacé par un alignement personnalisé propre à la bibliothèque. Si les détails d'alignement ne sont pas fournis dans la documentation de la bibliothèque native, l'alignement correct devra être déterminé par tâtonnement lors de l'implémentation du wrapper Java.

Exemple

Le programme suivant charge l'implémentation locale de la bibliothèque standard C et l'utilise pour appeler la fonction printf .

Remarque : Le code suivant est portable et fonctionne de la même manière sur les plateformes Windows et POSIX ( Linux / Unix / macOS ).

: "c") ), CLibrary . class ); void printf ( String format , Object ... args ); }public static void main ( String [] args ) { CLibrary.INSTANCE.printf ( " Hello , World " ) ; for ( int i = 0 ; i < args.length ; i ++ ) { CLibrary.INSTANCE.printf ( " Argument %d: % s \ n " , i , args [ i ] ) ; } } }

Le programme suivant charge la bibliothèque C POSIX et l'utilise pour appeler la fonction standard mkdir .

Remarque : Le code suivant est portable et fonctionne de la même manière sur les plateformes conformes aux normes POSIX .

c" , Posix.class ) ; // mais cela échouera toujours sous Windows car /tmp est manquant. posix.mkdir ( " /tmp/newdir" , 0777 ); posix.rename ( " /tmp/newdir" , " / tmp/renamedir" ); } }

Le programme ci-dessous charge le fichier Kernel32.dll et l'utilise pour appeler les fonctions Beep et Sleep .

Remarque : Le code suivant fonctionne uniquement sur les plateformes Windows .

kernel32 " , Kernel32.class ) ; lib.Beep ( 698 , 500 ) ; lib.Sleep ( 500 ) ; lib.Beep ( 698 , 500 ) ; } }