vendredi 11 septembre 2009

java : JNI ....

JNI (Java Native Interface) permet d'appeler des fonctions natives tel que du C/C++. Voici la marche à suivre :

1- tout d'abord, il faut créer une classe java qui comporte des méthodes natives ... et utiliser l'outil de SUN javah qui va générer un header C pour les méthodes natives ...

Voici un exemple de classe :


package com.jni;

public class JNITest {

// chargement de la librairie
static
{
System.loadLibrary("nativeLib");
}

public native String concat(String s2,String s1);

public native long testLong(long valeur);
/**
* @param args
*/
public static void main(String[] args)
{
System.out.println("debut test JNI");
JNITest obj = new JNITest();
String result = obj.concat("abc","def");
System.out.println("valeur retournee = [" + result + "]");

long valeur = -1;
valeur = obj.testLong(0);
System.out.println("long retourne = [" + valeur + "]");
System.out.println("fin test JNI");
}
}


lancer javah et ajouter le chemin vers le fichier .class

C:\Program Files\Java\j2sdk1.4.2_08\bin\javah.exe D:\Projets\workspace_bc\testJNI\bin\com.ldu.JNITest

A noter, que dans cette classe, il faut charger en static la librairie générée (dll ou .so selon la plateforme)


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


2-Si tout s'est bien passé alors, un fichier header (*.h) a été généré. Il suffit maintenant d'implémenter les méthodes avec un fichier *.c ou *.cpp (Attention dans le cas du C++, il faut encadred les méthodes par un extern c,car en fait ce sont des fonctions c et les nom ne doivent pas être décorés ...

Voici, l'exemple d'implémentation des méthodes c

/* ========================================================================== */
/* */
/* Filename.c */
/* (c) 2001 Author */
/* */
/* Description */
/* */
/* ========================================================================== */
#include
#include
#include "com_ldu_JNITest.h"

JNIEXPORT jstring JNICALL Java_com_ldu_JNITest_concat
(JNIEnv * env, jobject obj, jstring chaine1, jstring chaine2)
{
char resultat[256];
const char *str1 = (*env)->GetStringUTFChars(env, chaine1, 0);
const char *str2 = (*env)->GetStringUTFChars(env, chaine2, 0);
sprintf(resultat,"%s%s", str1, str2);
(*env)->ReleaseStringUTFChars(env, chaine1, str1);
(*env)->ReleaseStringUTFChars(env, chaine2, str2);
return (*env)->NewStringUTF(env, resultat);
}

JNIEXPORT jlong JNICALL Java_com_ldu_JNITest_testLong
(JNIEnv * env, jobject obj , jlong valeur)
{
return valeur + 1;
}


3-Une fois les méthodes implémentées, il faut maitenant les compiler, par exemple avec mingw (portage de gcc sous windows) ...
Voici un exemple de ligne de commande


D:\tools\bin\gcc.exe -I "C:\Program Files\Java\j2sdk1.4.2_08\include" -I "C:\Program Files\Java\j2sdk1.4.2_08\include\win32" -c "D:\Projets\workspace_bc\testJNI\bin\com_ldu_JNITest.c"


4-Il est ensuite nécessaire de générer la libriarie:
Voici la ligne de comande
D:\tools\bin\gcc.exe -shared -Wl,--kill-at "D:\Projets\workspace_bc\testJNI\bin\com_ldu_JNITest.o" -o nativeLib.dll

5-et surtout de la mettre dans le java.library.path
java com.ldu.JNITest-Djava.library.path="D:\Projets\workspace_bc\testJNI\bin"



Aucun commentaire:

Enregistrer un commentaire