Anda di halaman 1dari 35

Exécuter du code natif en Java : JNI VS JNA

par Mickael BARON alias Keulkeul (Page perso)


Frédéric Martini alias adiguba (Page perso)

Date de publication : 27/03/2008

Dernière mise à jour : 27/03/2008

JNI (Java Native Interface) et JNA (Java Native Access) sont deux
technologies qui permettent d'adresser du code natif dans du code Java. Nous
explorerons dans cet article une comparaison de ces deux technologies en
les appliquant à un même exemple dans le but de dresser un bilan de leur
utilisation.

Cet article est une version plus étoffée d'un billet posté par adiguba sur le
blog Java de Developpez.com

Les sources de l'exemple sont disponibles à l'adresse suivante : FTP ou HTTP.


Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

I - Introduction
II - Pré-requis logiciels
II-1 - Eclipse IDE
II-2 - MingW
II-3 - C/C++ Development Tools (CDT)
II-4 - Java Native Interface (JNI)
II-5 - Java Native Access (JNA)
II-6 - Librairies Dynamiques
III - Exemple
IV - JNI
IV-1 - Déclarer les méthodes natives
IV-2 - Générer le header C/C++
IV-3 - Implémenter le code natif
IV-4 - Compiler et générer la librairie native (en ligne de commandes)
IV-5 - Compiler et générer la librairie native (via CDT)
IV-6 - Charger la librairie native
IV-7 - Bilan
V - JNA
V-1 - Déclarer les méthodes natives dans une interface
V-2 - Instancier dynamiquement l'interface de déclaration
V-3 - Bilan
VI - Conclusion
VII - Pour aller plus loin ...
VIII - Remerciements

-2-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

I - Introduction

"Write once, run anywhere" : le slogan du langage Java a toujours mis en avant la portabilité du langage et de
ses APIs, tout en promettant qu'un même code pourra être exécuté sur n'importe quelle plateforme. Le compromis
apporté par cette portabilité est que les APIs se trouvent ainsi dépourvues de certaines fonctionnalités qui peuvent
sembler "basiques" pour un système, mais qui ne sont pas forcément disponibles sur d'autres (exemple : gestion de
la transparence des fenêtres). Bien que Java a récemment incorporé des fonctionnalités propre à certains systèmes
hôte, il est toujours nécessaire de faire appel à du code natif dés que les besoins s'approchent un peu trop du système.

L'objectif de cet article est de mettre en avant des technologies permettant d'adresser du code natif dans du code
Java. Nous tenterons ainsi de lister leurs défauts et leurs avantages en vue de choisir au mieux la technologie adaptée
selon les circonstances.

Deux technologies seront présentées :

• La première technologie s'appelle JNI (Java Native Interface). Elle est fournie par défaut par le JDK et
nécessite de manipuler un langage natif pour effectuer les appels aux fonctions natives.
• La seconde technologie s'appelle JNA (Java Native Access). C'est une API tiers qui offre l'avantage de
s'abstraire de la couche native.

Le plan présenté par cet article est le suivant. Nous décrivons dans une première section l'ensemble des pré-requis
logiciels utilisé. Puis, dans une deuxième section, nous détaillons l'étude de cas fil rouge qui sera appliquée aux deux
technologies. Les sections trois et quatre appliquent l'étude de cas respectivement avec les technologies JNI et JNA.
Pour chaque technologie, nous détaillons les étapes de développement et nous dressons un bilan. Finalement, nous
terminons cet article par une conclusion.

-3-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

II - Pré-requis logiciels

Cette section présente tous les outils qui ont été utilisés dans le cadre de cet article. Nous renseignons volontairement
pour chaque outil, la version utilisée lors de la réalisation de cet article.

• Eclipse IDE : l'environnement de développement Java (version 3.3.0)


• MingW : le compilateur C/C++ pour la plateforme Windows (version 5.1.3)
• Projet CDT : l'environnement de développement C, nécessaire pour la partie JNI (vers 4.0.1)
• Librairie JNA (vers 3.0) : les librairies pour utiliser JNA

Nous détaillerons pour chacun de ces outils la procédure d'installation et de configuration en montrant également les
interconnexions entre les différents outils et librairies (configuration de MingW avec Eclipse CDT).

II-1 - Eclipse IDE

L'environnement de développement Eclipse sera utilisé pour la gestion des langages Java et C/C++ (voir partie
suivante pour l'installation et la configuration de la plateforme C/C++).

Le téléchargement de l'environnement de développement est obtenu sur le site de la fondation Eclipse :


www.eclipse.org/downloads/

Pour l'installation, rien de difficile, décompressez l'archive dans le répertoire où vous installez généralement vos
applications (par exemple : c:\program files).

II-2 - MingW

MinGW est l'acronyme de Minimalist Gcc for Windows. Ce projet apporte une collection d'outils permettant de
produire du code natif pour la plateforme Windows. Il s'agit en fait d'une adaptation des outils de développement du
GNU du monde Linux à la plateforme Windows. Concrètement, MinGW va nous fournir l'outil GCC pour effectuer
nos compilations et nos liaisons de la DLL construite pour la partie JNI.

Le site du projet MinGW : www.mingw.org

La page de téléchargement via SourceForge : MinGW-5.1.3.exe

Téléchargez la version estampillée Automated MinGW Installer. L'installation de MinGW est relativement simple.
Suivez les informations du Wizard. Choisissez le répertoire d'installation par défaut c:\MinGW. Prenez soin également
de cocher les packages comme indiqués ci-dessous :

• MinGW base tools : contient les éléments basiques pour compiler du C;


• MinGW Make : pour faciliter la compilation et l'édition des liens. CDT en aura besoin.

Si l'installation s'est effectuée sans problème, vous devriez avoir un répertoire MinGW à la racine du lecteur C.
Pour finaliser l'installation de MinGW, il faut procéder au renommage de l'outil mingw32-make.exe en make.exe pour
qu'Eclipse CDT puisse retrouver sans problème cet outil qu'il utilise.

II-3 - C/C++ Development Tools (CDT)

-4-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Eclipse CDT (C/C++ Developement Tools) est un environnement pour la gestion de projets C/C++. Il offre toutes les
fonctionnalités pour associer un compilateur et un linkeur à un projet C/C++. Il s'occupe également de toute la gestion
de la construction d'exécutable et de librairie dynamique. Concernant l'installation, deux solutions sont possibles.

Installer CDT dans un environnement Eclipse pré-installé : une première solution s'appuie sur un environnement
Eclipse existant puisque le projet CDT repose sur un Eclipse. Si vous suivez cette solution l'installation pourra se
faire via le gestionnaire de mise à jour appelé update manager.

Vous trouverez ci-dessous les différents écrans pour installer CDT via l'outil de mise à jour :

Pour ouvrir l'outil de mise à jour, sélectionner le menu Help --> Software Updates --> Find and Install.

-5-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Choisissez ensuite la recherche de nouvelles features. Une feature peut être vue comme un groupe spécifique de
plugins. Elle contient également un ensemble de méta-données pour donner une description au groupe. Ici, nous
installons la feature CDT.

-6-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Sélectionnez ensuite le site de mise à jour Europa Discovery Site utilisé pour installer de nouvelles features propre
à la version Eclipse Europa.

-7-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Choisissez le serveur de téléchargement : soit le site officiel de Europa Discovery Site soit un site miroir.

-8-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Sélectionner la feature Eclipse C/C++ Development Tools pour l'installer. Remarquez sur la capture d'écran que les
features sont regroupées par catégorie.

-9-
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Acceptez ensuite les termes de la licence d'agrément concernant la feature CDT.

- 10 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Choisissez le répertoire d'installation, laissez par défaut le répertoire de votre environnement Eclipse.

- 11 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Le téléchargement des plugins de CDT est alors lancé.

- 12 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Veuillez accepter le contrat avant l'installation de CDT.

- 13 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Après l'installation de la feature CDT, un redémarrage de l'environnement Eclipse est nécessaire.

Installer un environnement Eclipse CDT : Une seconde solution consiste à télécharger un environnement
spécialisé uniquement pour le développement de projets C/C++. Il ne contiendra donc pas les plugins liés à la
plateforme JDT (Java Development Tool).

Le téléchargement de l'environnement de développement est obtenu sur le site de la fondation Eclipse :


www.eclipse.org/cdt/downloads.php

Le compilateur C/C++ et les environnements de développement (Java et C/C++) sont installés. La configuration de
MingW depuis Eclipse est automatique. Eclipse CDT reconnaît automatiquement le compilateur.

Dans le cadre de la mise en place des exemples de cet article nous employons la première solution puisque nous
travaillons à la fois sur des projets Java et C/C++. Il suffira donc de changer de perspective pour passer d'une
plateforme de développement Java à C/C++ et vice et versa.

Comme à chaque fois qu'un nouvel environnement de développement est installé, le reflexe du développeur (je parle
en mon nom) est de le tester via l'exemple tout simple : hello world. Vous trouverez donc ci-dessous un mini-tutoriel
sur la manière de créer l'éternelle application hello world en C/C++ avec Eclipse CDT et MingW.

- 14 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Sélectionnez à partir de l'assistant d'Eclipse, la création d'un nouveau projet C++.

- 15 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Cet écran vous propose de définir le nom du projet et le type de projet. Pour l'exemple HelloWorld, choisissez le
wizard Hello Wold C++ project. Dans la partie JNI, nous choisirons un projet de type Shared Library pour construire
une DLL. Notez enfin que sur la partie droite, le compilateur peut être choisi.

- 16 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Définissez des propriétés liées à l'auteur essentiellement concernant le projet en construction.

- 17 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Choisissez enfin la configuration pour le déploiement (Debug et/ou Release).

La fin de l'assistant génère le projet HelloWorld et un fichier helloworld.c présenté ci-dessus :

#include <iostream>
using namespace std;

int main() {
cout << "!!!Hello World!!!" << endl; // prints !!!Hello World!!!
return 0;
}

La compilation est gérée par Eclipse CDT soit de manière automatique (à chaque sauvegarde d'une modification)
soit de manière explicite (compilation demandée par le développeur). Si aucune erreur n'est trouvée, il ne vous reste
plus qu'à exécuter l'exemple qui a été généré dans le répertoire du projet HelloWorld.

- 18 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

II-4 - Java Native Interface (JNI)

JNI (Java Native Interface) est une couche de programmation qui permet à du code Java d'appeler ou d'être appelé
par du code natif. Il n'existe pas réellement de bibliothèque à télécharger pour faire du JNI puisque cette couche de
programmation est fournie par défaut dans le JDK. Toutefois, au moment de la création de projet JNI, des fichiers
header (identification de la JVM par exemple) devront être liés lors de la phase de liaison.

Les fichiers header sont disponibles à la racine du répertoire JDK dans les répertoires %JAVA_HOME%\include et
%JAVA_HOME%\include\win32 suivant le type de système d'exploitation que vous utilisez. Dans notre cas il s'agit
de la plateforme Win32.

II-5 - Java Native Access (JNA)

JNA (Java Native Access) est une API permettant d'accéder à du code natif sans faire appel explicitement à la couche
de programmation JNI. Le développement nécessite une interface Java pour décrire le prototype les fonctions et les
structures contenues dans le code natif à appeler.

Ce projet est en incubation et pourrait être disponible dans les prochaines versions de Java.

Contrairement à JNI, l'utilisation de JNA nécessite le téléchargement d'une biblioth#que spécifique. Vous trouverez
donc sur le site la librairie JNI à télécharger puis de nombreux exemples mettant en oeuvre cette bibliothèque.

• Site de JNA : jna.dev.java.net


• Bibliothèque JNA : jna.dev.java.net/servlets/ProjectDocumentList

II-6 - Librairies Dynamiques

Par défaut, Java respecte les conventions du système hôte pour le chargement des librairies natives, c'est à dire :

• Sous Windows, les librairies seront recherchées dans le PATH.


• Sous Unix/Linux, elles sont recherchées dans le LD_LIBRARY_PATH.
• Sous Mac OS, c'est la variable d'environnement DYLD_LIBRARY_PATH qui est utilisée.

Il est possible d'outrepasser cela en modifiant la variable système java.library.path (ou jna.library.path pour JNA que
nous verrons un peu plus loin). Si la librairie ne fait pas partie d'un des répertoires spécifiés, l'exécution du programme
génèrera une UnsatisfiedLinkError.

De même, chaque système possède ses propres conventions pour le nommage des fichiers représentant les
librairies, par exemple pour une librairie nommée hello :

• Sous Windows, on lui ajoute simplement l'extension .dll, soit hello.dll


• Sous Unix/Linux, on utilise le prefixe lib couplé à l'extension .so, soit libhello.so
• Sous Mac OS, on utilise le prefixe lib couplé à l'extension .jnilib, soit libhello.jnilib

- 19 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

III - Exemple

Cet article est illustré via un exemple simpliste montrant l'utilisation de fonctions natives permettant la gestion de la
transparence pour les fenêtres et boîtes de dialogues.

La fonctionnalité de transparence des fenêtres existe sur la plupart des systèmes récents : Windows (à partir de XP),
MacOSX et Linux. La démarche d'utilisation de JNI et JNA étant la même sur toutes les plateformes, nous nous
limiterons donc à la plateforme Windows.

La mise en transparence d'une fenêtre pour la plateforme Windows est obtenue en appelant dans un premier temps
la fonction SetWindowLong pour extraire de l'handle Window la couche qui deviendra transparente. Dans un second
temps il faut faire appel à la fonction SetLayeredWindowAttributes pour choisir le type de transparence et activer
la transparence.

Deux types de transparence sont à distinguer :

• locale à une couleur, en indiquant la couleur en question;


• globale à toute la fenêtre, en indiquant le niveau d'opacité.

Malheureusement, l'API Win32 ne permet de préciser un niveau d'opacité pour une


couleur donnée. Par contre il est possible, et nous allons le montrer dans la suite de cet
article, de combiner les deux types de transparence pour obtenir une fenêtre avec une
couleur transparente et un niveau d'opacité pour la fenêtre complète.

Du côté client Java, nous utiliserons la boîte à outils SWT de la plateforme Eclipse. L'API SWT manipule des
composants graphiques de type heavyheight. Il devient relativement facile d'accéder aux handles des composants
et par conséquent à l'handle window de la fenêtre à rendre transparente.

Nous montrons ci-dessous deux captures d'écran de l'application que nous souhaitons rendre transparente. La
première capture représente l'interface sans activation de la transparence tandis que la seconde présente la même
interface avec la transparence activée. Il est à noter que le composant du dessous (un conteneur) a une couleur
non conventionnelle. En effet, nous souhaitons isoler cette zone pour la rendre totalement transparence. Par contre
concernant le reste de la fenêtre nous définirons un niveau d'opacité de manière à voir à travers la fenêtre.

- 20 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Transparence non activée

Transparence activée

Vous trouverez ci-dessous le code de l'application utilisée comme support aux appels des fonctions natives WIN32.

public class TransparencyExample {

private static final boolean isJNIImplementation = true;

private final byte opacity = (byte)200;

public TransparencyExample() {
final Display display = new Display();
final Shell myShell = new Shell(display, SWT.SHELL_TRIM | SWT.ON_TOP);
myShell.setText("Transparency Example");
myShell.setLayout(new FillLayout(SWT.VERTICAL));

final Button myButton = new Button(myShell,SWT.NONE);


myButton.setText("Go To The Transparency Dream");

final Composite myComposite = new Composite(myShell, 0x80000);


Color colorDarkBlue = Display.getDefault().getSystemColor(SWT.COLOR_DARK_BLUE);

- 21 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

myComposite.setBackground(colorDarkBlue);

myShell.setSize(400, 200);
myShell.setLocation(0, 0);
myShell.open();

createTransparency(myShell.handle, colorDarkBlue.handle, opacity);

while(!myShell.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}

private void createTransparency(int hWindow, int hColor, byte opacity) {


if (isJNIImplementation) {
// Appel des fonctions déclarées par JNI
} else {
// Appel des fonctions déclarées par JNA
}
}

public static void main(String[] argv) {


new TransparencyExample();
}

Dans un premier nous réaliser la construction de l'interface utilisateur (un bouton et un conteneur). La couleur
COLOR_DARK_BLUE dans la zone du conteneur va nous permettre d'isoler cette zone et la rendre transparente.
L'activation de la transparence est obtenue en appelant la méthode createTransparency en lui passant l'handle de
la fenêtre, la couleur à rendre transparente (zone totalement transparente) et le niveau d'opacité (transparence du
reste de la fenêtre).

Concernant la méthode createTransparency, son rôle est d'appeler les fonctions natives selon la logique définie
précédemment. L'appel aux fonctions natives sera effectué soit via JNI soit via JNA. Ici, l'aiguilleur est représenté
par un booléen isJNIImplementation.

L'intérêt de cet article est de montrer comment définir le pont entre la partie native et la partie Java en employant
deux technologies : JNI et JNA.

Les sources de l'exemple sont disponibles à l'adresse suivante : FTP ou HTTP.

Deux projets Eclipse sont fournis. Le premier developpez.jnijna contient la partie Java. Le second
developpez.jnijna.native implémente la partie native. Copiez les deux répertoires dans le workspace de votre Eclipse
et importer les à partir de l'assistant d'Eclipse.

- 22 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

IV - JNI

Rappelons que JNI est une passerelle qui permet de faire un appel à une fonction native. Toutefois, l'appel n'est
pas direct. Il est ainsi obligatoire de définir une méthode native qui respecte un prototype précis. De ce fait il devient
obligatoire de passer par une méthode intermédiaire qui englobera cet appel.

La décomposition de cette section est réalisée comme suit :

• déclarer les méthodes natives : définir les méthodes intermédiaires qui permettent d'appeler les fonctions
natives.
• générer le header c/c++ : générer l'en-tête du fichier C/C++ correspondant aux fonctions natives à exporter
tout en respectant le prototype défini précédemment.
• implémenter le code natif : implémentation des méthodes déclarées dans le fichier header.
• compiler et générer la librairie native : construire la dll dont la fonctionnalité est de fournir les services définis
par l'en-tête.
• charger la librairie native : charger la bibliothèque dans le programme Java, le pont est maintenant construit.

IV-1 - Déclarer les méthodes natives

La première étape consiste donc à écrire le prototype Java des méthodes natives. Dans le code de la classe
JNIUser32 qui suit, trois méthodes correspondant respectivement aux méthodes natives à appeler ont été
définies (GetWindowLong, SetWindowLong et SetLayeredWindowAttributes). Ainsi, la logique d'appel aux différentes
fonctions natives pour activer la transparence de la fenêtre est à la charge de la partie Java. Au contraire, nous
aurions pu fournir une seule méthode native qui aurait eu à sa charge d'effectuer les différents traitements de gestion
de la transparence.

package developpez.jnijna;

public final class JNIUser32 {

public static final int LWA_COLORKEY = 1;

public static final int LWA_ALPHA = 2;

public static final int WS_EX_LAYERED = 0x80000;

public static final int GWL_EXSTYLE = -20;

public static final native int GetWindowLong(int hWnd, int nIndex);

public static final native int SetWindowLong(int hWnd, int nIndex, int dwNewLong);

public static final native boolean SetLayeredWindowAttributes(int hwnd, int crKey, byte bAlpha,
int dwFlags);
}

Ce code peut être compilé normalement sans problème puisque le compilateur ne vérifie pas les liens vers les
méthodes natives (ne charge par la librairie dynamique), par contre l'exécution génèrera une belle exception puisque
les méthodes natives correspondantes n'existent pas encore ...

IV-2 - Générer le header C/C++

- 23 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Une fois cette classe compilée, il faut utiliser l'outil javah sur la classe générée et non sur le code source. L'outil javah,
fourni avec le JDK, permet de générer un fichier d'en-tête C/C++. Ce dernier s'utilise comme la commande java et
nécessite donc un nom de classe complet (c'est-à-dire avec le package) :

javah developpez.jnijna.JNIUser32

Ce qui nous génèrera dans le cas présent un fichier nommé developpez_jnijna_JNIUser32.h contenant le code
suivant :

/* DO NOT EDIT THIS FILE - it is machine generated */


#include <jni.h>
/* Header for class developpez_jnijna_JNIUser32 */

#ifndef _Included_developpez_jnijna_JNIUser32
#define _Included_developpez_jnijna_JNIUser32
#ifdef __cplusplus
extern "C" {
#endif
#undef developpez_jnijna_JNIUser32_LWA_COLORKEY
#define developpez_jnijna_JNIUser32_LWA_COLORKEY 1L
#undef developpez_jnijna_JNIUser32_LWA_ALPHA
#define developpez_jnijna_JNIUser32_LWA_ALPHA 2L
#undef developpez_jnijna_JNIUser32_WS_EX_LAYERED
#define developpez_jnijna_JNIUser32_WS_EX_LAYERED 524288L
#undef developpez_jnijna_JNIUser32_GWL_EXSTYLE
#define developpez_jnijna_JNIUser32_GWL_EXSTYLE -20L
/*
* Class: developpez_jnijna_JNIUser32
* Method: GetWindowLong
* Signature: (II)I
*/
JNIEXPORT jint JNICALL Java_developpez_jnijna_JNIUser32_GetWindowLong
(JNIEnv *, jclass, jint, jint);

/*
* Class: developpez_jnijna_JNIUser32
* Method: SetWindowLong
* Signature: (III)I
*/
JNIEXPORT jint JNICALL Java_developpez_jnijna_JNIUser32_SetWindowLong
(JNIEnv *, jclass, jint, jint, jint);

/*
* Class: developpez_jnijna_JNIUser32
* Method: SetLayeredWindowAttributes
* Signature: (IIBI)Z
*/
JNIEXPORT jboolean JNICALL Java_developpez_jnijna_JNIUser32_SetLayeredWindowAttributes
(JNIEnv *, jclass, jint, jint, jbyte, jint);

#ifdef __cplusplus
}
#endif
#endif

Normalement vous n'avez pas à toucher le code de ce fichier en-tête puisqu'il a été
complètement généré. Toute nouvelle génération annulera les éventuelles modifications
que vous pourriez apporter à ce fichier.

IV-3 - Implémenter le code natif

- 24 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Il est maintenant nécessaire de coder les fonctions natives correspondant au prototype généré, ce qui donne pour
notre étude de cas le résultat suivant :

#define WINVER 0x0500


#include <jni.h>
#include <stdio.h>
#include <windows.h>
#include "developpez_jnijna_JNIUser32.h"

JNIEXPORT jint JNICALL Java_developpez_jnijna_JNIUser32_GetWindowLong


(JNIEnv *env, jclass theClass, jint windowHandle, jint nIndex) {
jint rc = 0;
rc = (jint)GetWindowLongA((HWND)windowHandle, nIndex);
return rc;
}

JNIEXPORT jint JNICALL Java_developpez_jnijna_JNIUser32_SetWindowLong


(JNIEnv *env, jclass theClass, jint windowHandle, jint nIndex, jint dwNewLong) {
jint rc = 0;
rc = (jint)SetWindowLongA((HWND)windowHandle, nIndex, dwNewLong);
return rc;
}

JNIEXPORT jboolean JNICALL Java_developpez_jnijna_JNIUser32_SetLayeredWindowAttributes


(JNIEnv *env, jclass theClass, jint windowHandle, jint hColor, jbyte alpha, jint flags) {
SetLayeredWindowAttributes((HWND)windowHandle,hColor,alpha,flags);
return( 0 );
}

IV-4 - Compiler et générer la librairie native (en ligne de commandes)

Il nous faut désormais compiler ce bout de code. Pour cela il faut spécifier au compilateur l'emplacement des headers
natif de JNI qui se trouvent dans le répertoire include du JDK, ce qui nous donne (la variable d'environnement
JAVA_HOME pointant vers le chemin d'installation du JDK) :

g++ -I"%JAVA_HOME%\include" -I"%JAVA_HOME%\include\win32" -c developpez_jnijna_JNIUser32.cpp

La librairie dynamique peut enfin être générée, que l'on nommera transparency.dll

g++ -Xlinker --add-stdcall-alias -shared -otransparency.dll developpez_jnijna_JNIUser32.o

L'option supplémentaire --add-stdcall-alias indique au linkeur qu'il ne doit pas décorer nom des fonctions exportées,
car cela empêcherait JNI de faire correspondre les noms des méthodes définis dans le prototype et ceux de la
bibliothèque dynamique.

La seconde option -otransparency.dll impose un nom à la bibliothèque lors de la sortie de la compilation et à la liaison.

IV-5 - Compiler et générer la librairie native (via CDT)

Avant de procéder à la compilation, il faut paramétrer le linkeur de manière à ce qu'il ne décore pas le nom des
fonctions exportées (comme montré dans la section précédente).

Ouvrez le menu propriétés de projet et sélectionnez les options C/C++ Build -> Settings. Vous devrez obtenir l'écran
ci-dessous. Ajouter les deux options à la configuration de votre projet.

- 25 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

- 26 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Propriétés d'un projet CDT

Enfin concernant la compilation via l'outil CDT, elle est pilotée par l'outil. Elle est réalisée soit de manière implicite, si
l'option Build Automatically est activée (menu Project), soit de manière explicite, si l'action Build Project est utilisée
(également dans le menu Project).

IV-6 - Charger la librairie native

Il reste une petite modification à effectuer sur le code source de notre classe Java : il est impératif de charger
cette librairie pendant le chargement de la classe afin que les méthodes natives puissent être utilisées sans
problème.

Pour cela il suffit d'ajouter un bloc static dans le corps de la classe avec l'instruction System.loadLibrary :

package developpez.jnijna;

public final class JNIUser32 {

static {
System.loadLibrary("libdeveloppez.jnijna.native");
}

public static final int LWA_COLORKEY = 1;

public static final int LWA_ALPHA = 2;

public static final int WS_EX_LAYERED = 0x80000;

public static final int GWL_EXSTYLE = -20;

public static final native int GetWindowLong(int hWnd, int nIndex);

public static final native int SetWindowLong(int hWnd, int nIndex,


int dwNewLong);

public static final native boolean SetLayeredWindowAttributes(int hwnd,


int crKey, byte bAlpha, int dwFlags);
}

Lors de l'utilisation de la méthode loadLibrary ne pas préciser l'extension de la


bibliothèque.

On peut désormais utiliser nos méthodes natives directement dans notre code java de manière tout à fait standard :

private void createTransparency(int hWindow, int hColor, byte opacity) {


if (isJNIImplementation) {
int flags = JNIUser32.GetWindowLong(hWindow, JNIUser32.GWL_EXSTYLE);
flags |= JNIUser32.WS_EX_LAYERED;
JNIUser32.SetWindowLong(hWindow, JNIUser32.GWL_EXSTYLE, flags);
JNIUser32.SetLayeredWindowAttributes(hWindow, hColor, opacity,
JNIUser32.LWA_COLORKEY | JNIUser32.LWA_ALPHA);
} else {
// Appel des fonctions déclarées par JNA
}
}

IV-7 - Bilan

- 27 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Même si le code natif est relativement simple, il est quand même dommage de sortir l'artillerie. Pour un simple appel
de méthode, on se retrouve à suivre un protocole en cinq étapes :

• Déclarer des méthodes natives;


• Générer le header C/C++;
• Implémenter le code natif;
• Compiler et générer la librairie native;
• Charger la librairie native.

Par ailleurs, il faut également prendre en compte les aspects logistiques :

• Installation d'un compilateur C/C++;


• Disposer d'un environnement de développement pour le langage C/C++;
• De connaissance sur un autre langage que Java même si le code écrit ci-dessus n'est pas d'une grande
complexité.

Tout ceci est d'autant plus rageant lorsqu'on se contente d'appeler une fonction existante comme dans le cas présent,
et que ce type de code tient sur une ligne dans n'importe quel langage natif (et généralement totalement transparent).
Sans compter que l'on devra générer et déployer une librairie par système supporté. Bref rien de très intéressant à
coder, mais une source de problème potentiellement...

- 28 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

V - JNA

JNA se présente comme une alternative beaucoup plus simple d'accès, en permettant d'accéder dynamiquement à
n'importe quelle bibliothèque partagée du système sans utiliser JNI. En fait il s'agit de la bibliothèque fournie avec
JNA qui s'occupe du chargement des librairies dynamiques, de l'appel des fonctions, de la définition des structures
et de la conversion des types ... si bien que toutes les étapes fastidieuses liées à la manipulation de code C/C++
pour réaliser la passerelle entre Java et le code natif sont rendues très simples.

V-1 - Déclarer les méthodes natives dans une interface

Contrairement à JNI, la démarche à respecter est assez différente puisqu'il ne faut plus marquer les méthodes avec le
mot-clé native d'une part et qu'il est impératif d'utiliser une interface qui contiendra les définitions des fonctions natives
d'autre part (et seulement celles-ci). Cette interface doit obligatoirement étendre l'interface com.sun.jna.Library (ou
tout autre sous interface fournie par l'API) qui fait office de marqueur.

A l'exécution une instance valide de cette interface pourra être récupérée. Cette instance sera automatiquement liée
à la librairie native et elle sera utilisée pour réaliser directement les appels aux méthodes natives.

Appliquons dés à présent cette description à notre exemple. Nous déclarons toutes les fonctions dans l'interface
particulière JNAUser32 décrite ci-dessous :

package developpez.jnijna;

public interface JNAUser32 extends StdCallLibrary {

public static final int GWL_EXSTYLE = -20;


public static final int WS_EX_LAYERED = 0x80000;

public static final int LWA_COLORKEY = 1;


public static final int LWA_ALPHA = 2;

int GetWindowLong(int hWnd, int nIndex);


int SetWindowLong(int hWnd, int nIndex, int dwNewLong);

boolean SetLayeredWindowAttributes(int hwnd, int crKey, byte bAlpha, int dwFlags);


}

JNAUser32 étend l'interface StdCallLibrary qui permet de préciser que les fonctions sont déclarées suivant la
convention d'appel stdcall. Pour faire simple cette convention d'appel, propre à la gestion des librairies Win32, permet
d'indiquer que l'ordre des paramètres des fonctions est défini de gauche à droite.

Au niveau du contenu de cette interface, nous définissons de la même manière que pour JNI les constantes utilisées
lors de l'appel aux fonctions natives. La déclaration des fonctions natives est elle aussi similaire à la démarche JNI
hormis le fait que le mot-clé native n'est plus utilisé.

Enfin, la librairie s'occupe elle-même de faire toutes les conversions de type et de rechercher les fonctions natives
à appeler dynamiquement selon la définition de la méthode Java, si bien qu'il n'y a pas besoin d'écrire une seule
ligne de code natif !

V-2 - Instancier dynamiquement l'interface de déclaration

- 29 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Il ne reste plus qu'à créer une instance de l'interface JNAUser32 qui sera automatiquement liée à la librairie
native. Pour cela la méthode Native.loadLibraty est utilisée en lui précisant le type Java de l'interface, le nom de la
bibliothèque dynamique native et quelques paramètres d'initialisation du chargement. Premier constant et pas des
moindres, cette solution via JNA permet donc de charger directement une librairie dynamique dépourvue de tout
artifice nécessaire pour une utilisation dans Java. Il est par conséquent tout à fait possible d'utiliser n'importe quelle
bibliothèque native sous condition de connaître son API.

Vous trouverez ci-dessous la modification apportée à l'interface JNAUser32 permettant le chargement de la


bibliothèque et l'instanciation de l'interface.

package developpez.jnijna;

public interface JNAUser32 extends StdCallLibrary {

Map UNICODE_OPTIONS = new HashMap() {


{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.UNICODE);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.UNICODE);
}
};

Map ASCII_OPTIONS = new HashMap() {


{
put(OPTION_TYPE_MAPPER, W32APITypeMapper.ASCII);
put(OPTION_FUNCTION_MAPPER, W32APIFunctionMapper.ASCII);
}
};

Map DEFAULT_OPTIONS = Boolean.getBoolean("w32.ascii") ? ASCII_OPTIONS : UNICODE_OPTIONS;

JNAUser32 INSTANCE = (JNAUser32) Native.loadLibrary("user32", JNAUser32.class, DEFAULT_OPTIONS);


}

Enfin, il suffit d'utiliser l'instance ainsi créée pour appeler les fonctions natives. La méthode createTransparency
pourra être complétée par le code suivant.

private void createTransparency(int hWindow, int hColor, byte opacity) {


if (isJNIImplementation) {
// Appel des fonctions déclarées par JNI
} else {
JNAUser32 lib = JNAUser32.INSTANCE;
int flags = lib.GetWindowLong(hWindow, JNAUser32.GWL_EXSTYLE);
flags |= JNAUser32.WS_EX_LAYERED;
lib.SetWindowLong(hWindow, JNAUser32.GWL_EXSTYLE, flags);
lib.SetLayeredWindowAttributes(hWindow, hColor, opacity,
JNAUser32.LWA_COLORKEY | JNAUser32.LWA_ALPHA);
}
}

Veuillez noter que la logique d'appel des différentes fonctions natives est similaire que ce soit pour JNI que pour
JNA. Toutefois, pour JNI les appels aux méthodes se font comme des méthodes de classes tandis que les appels
aux méthodes natives via JNA se font d'une manière tout à fait classique.

V-3 - Bilan

- 30 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

Si nous partons du même schéma de comparaison que pour le bilan de la solution JNI, pour réaliser un simple appel
de méthode via JNA, nous nous retrouvons à suivre un protocole en deux étapes :

• Déclarer les méthodes natives dans une interface;


• Instancier dynamiquement l'interface.

Concernant les aspects logistiques :

• Pas besoin d'installer un compilateur C/C++;


• Pas besoin de disposer d'un environnement de développement pour le langage C/C++;
• Pas besoin de connaissance dans un autre langage.

Tout cela est bien sur relatif et dépend fortement du besoin à traiter. Si vous souhaitez utiliser une bibliothèque
dynamique déjà existante, JNA conviendra à votre besoin. Par contre, si vous devez développer obligatoirement une
brique de votre logiciel en langage natif C/C++, les aspects logistiques vous seront nécessaires.

Même si nous n'avons fait que survoler les possibilités qu'offre JNA, et bien qu'il n'y ait qu'une documentation
succincte pour le moment, différents aspects pourront être traités dans un article plus approfondi sur le sujet, entre
autres les aspects suivants :

• Mapping Java/natif automatique des types primitifs et des String;


• Mapping des struct et des union vers des types Java spécifiques (Structure et Union);
• Mapping des pointeurs vers un type Java (ByReference);
• Mapping des pointeurs de fonctions (ou callback) en utilisant une interface Java;
• Possibilité de définir un mapping personnalisé pour ses propres objets Java;
• Mapping automatique de la méthode Java vers la fonction native du même nom, mais en gardant la
possibilité d'utiliser une classe qui se chargera de cela (par exemple pour utiliser des noms de méthodes
Java différent afin de respecter les règles de nommages Java);
• Gestion des librairies Win32 qui utilise la convention d'appel __stdcall.

- 31 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

VI - Conclusion

Nous avons étudié dans cet article deux solutions pour appeler du code natif. Une solution basée sur JNI fournie
initialement par la JDK et une seconde basée sur la bibliothèque externe JNA. Ces deux solutions ont été appliquées
sur un exemple simple qui fait appel à des fonctions natives WIN32 : activation de la transparence d'une fenêtre.

Nous avons montré que pour la solution JNI la difficulté était de devoir manipuler du code C/C++ (problématique liée
également à l'installation d'outils supplémentaires) alors que la solution JNA offrait l'avantage de s'abstraire de cette
couche de programmation. JNA fait office de pont implicite entre la bibliothèque dynamique et le code Java.

A l'heure du choix entre JNI et JNA, nous ne pouvons pas être catégoriques. L'exemple utilisé dans cet article n'est
pas représentatif de toute la couverture des besoins rencontrés. Le choix doit donc s'opérer selon les cas rencontrés.
Des besoins spécifiques amèneront à utiliser obligatoirement une solution à base de JNI. Nous ne l'avons pas montré
car cela sort du sujet de cet article mais il est parfois possible de communiquer dans la librairie avec la machine
virtuelle : communication C/C++ vers Java. De ce fait seule JNI le permet.

Mais il est indéniable que JNA permet de simplifier largement les appels aux fonctions natives.

- 32 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

VII - Pour aller plus loin ...

Pour plus d'information sur le sujet vous pouvez consulter les liens suivants :

• Java Native Interface, la documentation officielle


• Java Native Access, la page du projet sur java.net, et sa javadoc online
• NLink et NativeCall des projets similaires à JNA

- 33 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

VIII - Remerciements

Nous tenons à remercier Baptiste Wicht et Ricky81 pour leur relecture technique et elitost pour ses corrections
orthographiques.

- 34 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna
Exécuter du code natif en Java : JNI VS JNA par Mickael BARON alias Keulkeul (Page perso) Frédéric Martini alias adiguba (Page perso)

- 35 -
Ce document est issu de http://www.developpez.com et reste la propriété exclusive de son auteur. La copie, modification et/ou distribution par
quelque moyen que ce soit est soumise à l'obtention préalable de l'autorisation de l'auteur.
http://mbaron.developpez.com/javase/jnijna

Anda mungkin juga menyukai