Date de première publication : 2010/11/28
Java Native Interface (JNI) est un mécanisme permettant d’interfacer un programme Java avec un code natif. La communication peut se faire dans les deux sens mais je vous propose d’appeler dans un code Java une méthode/fonction écrite en C/C++.
Code
Java
Réutiliser le code permettant d’afficher l’équivalent d’un oscilloscope simple (si vous ne l’avez pas fait le code est disponible en téléchargement ici). Je vous propose d’externaliser le code de la fonction renvoyant soit un réel entre 0 et 1, soit un nombre entre 0 et une borne donnée.
public static native double fonction_native();
Le code natif doit se trouver dans une bibliothèque dynamique qu’il faut charger avant d’en avoir
besoin. Si la bibliothèque s’appelle libNOM.so
, il faut ajouter les lignes suivantes :
static {
System.load("NOM_AVEC_CHEMIN_COMPLET"); // OU
System.loadLibrary("NOM") ;
}
C
Voilà c’est presque terminé, la dernière étape est la création d’un fichier d'entête pour le programme C/C++. Il faut donner en paramètre le nom du fichier class (sans extension) contenant la déclaration de la fonction native.
javah –jni fichier_class_sans_extension
Regarder le fichier include généré par javah. Il contient la déclaration de la fonction dont on doit donner la définition.
Créer un fichier C faisant le travail demandé. Il faut inclure stdlib pour pouvoir utiliser la fonction
rand()
et la constante symbolique RAND_MAX
.
Liaison
Création d'une bibliothèque
Le plus « compliqué » reste la création de la bibliothèque avec la ligne suivante :
gcc fichier.c -o libNOM.so -shared -Wl,-soname,NOM.so
-I/…/include
–I/…/include/linux -fPIC -lc
Pour les répertoires donnés avec l’option –I, il faut trouver le répertoire contenant jni.h.
Par exemple :
/usr/lib/jvm/java-1.7.0-openjdk-1.7.0.71.x86_64/include
Pour cultance, l'option -Wl
permet de donner des options spéciales à -lc
permet de lier la bibliothèque c (libc.a
).
Exécution
Il ne reste plus qu’à exécuter le programme java avec la machine virtuelle. Si vous avez un message
d’erreur contenant l’emplacement de la bibliothèque, il faut s’assurer que la variable d'environnement LD_LIBRARY_PATH
est
correcte, par exemple sous bash :
LD_LIBRARY_PATH=`pwd`
export LD_LIBRARY_PATH
Compléments
Si cela vous intéresse, vous pouvez lire : http://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/jniTOC.html