Astuce Java 23: Écrire des méthodes natives

La possibilité d'écrire un seul ensemble de code en Java et de l'exécuter sur chaque système avec un environnement d'exécution Java est l'une des principales forces de Java. Mais cette indépendance de plate-forme a un inconvénient majeur: que faisons-nous avec la grande quantité de code existant? L'astuce consiste à utiliser la soi-disant interface de méthode native .

L'écriture de méthodes natives implique l'importation de code C dans votre application Java. Dans cette astuce, je vais vous expliquer la recette de base pour créer des méthodes natives et les utiliser dans une application Java.

Sept étapes vers la méthode native nirvana Les étapes de création de méthodes natives sont les suivantes:

  • Écrire du code Java
  • Compiler le code Java
  • Créer un en-tête C ( fichier .h )
  • Créer un fichier de stubs C
  • Ecrire le code C
  • Créer une bibliothèque de code partagée (ou DLL)
  • Lancer l'application

Notre exercice consiste à écrire du texte sur la console à partir de la méthode native. Les spécificités de cet exemple seront orientées vers un système de type Unix, en particulier Linux. Je vais souligner les quelques endroits où les détails diffèrent pour d'autres plates-formes.

Écrire du code Java

Écrivez votre code Java comme vous le feriez normalement. Pour utiliser des méthodes natives dans votre code Java, vous devez faire deux choses. Tout d'abord, écrivez une déclaration de méthode native pour chaque méthode native que vous souhaitez utiliser. C'est comme écrire la déclaration d'une interface de méthode Java normale, mais vous devez spécifier le mot-clé natif , comme suit:

public native void printText (); 

Le deuxième cercle à parcourir est que vous devez explicitement charger la bibliothèque de code native. (Nous créerons cela plus tard.) Nous faisons cela en chargeant la bibliothèque dans un bloc statique de classe:

static {System.loadLibrary ("heureux"); }

Pour rassembler ces éléments pour notre exemple, créez un fichier appelé Happy.javaavec le contenu suivant:

class Happy {public native void printText (); static {System.loadLibrary ("heureux"); / * Remarquez le nom de la classe en minuscules! * /} public static void main (String [] args) {Happy happy = new Happy (); happy.printText (); }}

Compiler le code Java

Compilez le Happy.javafichier:

% javac Happy.java 

Créer un fichier d'en-tête C

Il existe diverses incantations magiques qui doivent être rendues disponibles pour que notre code C puisse être utilisé comme méthode native. La javahfonctionnalité du compilateur Java générera les déclarations nécessaires et autres à partir de notre Happyclasse. Cela créera un Happy.hfichier à inclure dans notre code C:

% javah heureux 

Créer un fichier de stubs C

D'une manière qui rappelle la mutilation que les traducteurs C ++ font aux noms des méthodes C ++, le compilateur Java a une folie similaire. Pour soulager la douleur d'avoir à écrire beaucoup de code fastidieux afin que notre code C puisse être appelé à partir du système d'exécution Java, le compilateur Java peut générer automatiquement le code de trampoline nécessaire pour nous:

% javah -stubs Heureux 

Ecrire le code C

Maintenant, écrivons le code réel pour imprimer notre message d'accueil. Par convention, nous mettons ce code dans un fichier nommé d'après notre classe Java avec la chaîne "Imp" ajoutée. Cela se traduit par HappyImp.c. Placez les éléments suivants dans HappyImp.c:

#include & ltStubPreamble.h> / * Méthode native standard. * / #include "Happy.h" / * Généré plus tôt. * / #include & ltstdio.h> / * Trucs C IO standard. * / void Happy_printText (struct HHappy * this) {met ("Bonne année !!!"); }

Lors de l'interfaçage de votre code C avec Java, de nombreux autres aspects sont impliqués, tels que la manière de transmettre et de renvoyer la myriade de types. Pour plus d'informations, consultez le didacticiel Java ou le document Hermetica Native Methods (voir la section Ressources pour les URL).

Créer une bibliothèque partagée

This section is the most system-dependent. It seems like every platform and each compiler/linker combination has a different method of creating and using shared libraries. For folks using any of the various Microsoft Windows platforms, check the documentation for your C compiler for the nitty-gritty details.

For you Linux folks, here's how to create a shared library using GCC. First, compile the C source files that we have already created. You have to tell the compiler where to find the Java native method support files, but the main trick here is that you have to explicitly tell the compiler to produce Position Independent Code:

% gcc -I/usr/local/java/include -I/usr/local/java/include/genunix -fPIC -c Happy.c HappyImp.c 

Now, create a shared library out of the resulting object (.o) files with the following magical incantation:

% gcc -shared -Wl,-soname,libhappy.so.1 -o libhappy.so.1.0 Happy.o HappyImp.o 

Copy the shared library file to the standard short name:

% cp libhappy.so.1.0 libhappy.so 

Finally, you may need to tell your dynamic linker where to find this new shared library file. Using the bash shell:

% export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH 

Execute the application

Run the Java application as usual:

% java Happy 

Well, that's all there is to it. Thanks to Tony Dering for passing on the Linux-specific incantations.

A quick design note

Avant de nous précipiter pour écrire des méthodes natives pour tout ce code hérité, je vous conseille à tous d'examiner attentivement les systèmes existants et de voir s'il existe de meilleures façons de les connecter à Java. Par exemple, il existe Java Database Connectivity (JDBC) et même des solutions de niveau supérieur pour accéder aux bases de données à partir de Java. Alors, regardez toutes les astuces dans votre sac et utilisez ce qui a du sens pour le projet en cours.

En savoir plus sur ce sujet

  • JavaSoft Native Method Tuturial //www.javasoft.com/books/Series/Tutorial/native/implementing/index.html
  • Papier Hermetica Native Methods //www.hermetica.com/technologia/java/native/

Cette histoire, «Java Tip 23: Write native methods» a été publiée à l'origine par JavaWorld.