Bonjour,
Je souhaite écrire un HelloWorld pour JNI, mais celui-ci ne fonctionne pas.
Voici l'arborescence de mon projet :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12 . +-- bin | `-- test | `-- TestJNI.class +-- native | +-- testjni.so | +-- test_TestJNI.c | +-- test_TestJNI.h | `-- test_TestJNI.o `-- src `-- test `-- TestJNI.javaJ'ai généré test_TestJNI.h grâce à la commande suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 $ cat src/test/TestJNI.java package test; public class TestJNI { static { System.loadLibrary("testjni"); } public static native void helloWorld(); public static void main(String... args) { helloWorld(); } }
J'ai écrit mon fichier .c :
Code : Sélectionner tout - Visualiser dans une fenêtre à part javah -classpath bin -d native test.TestJNI
J'ai ensuite généré mon .so :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8 $ cat native/test_TestJNI.c #include <jni.h> #include <stdio.h> #include "test_TestJNI.h" JNIEXPORT void JNICALL Java_test_TestJNI_helloWorld(JNIEnv * env, jclass class) { printf("Hello world !\n"); }
J'ai besoin de -fPIC car mon système est une 64bits, sans quoi j'ai l'erreur suivante :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4 $ cd native $ gcc -fPIC -c test_TestJNI.c -o test_TestJNI.o -I/usr/lib/jvm/java-6-openjdk-amd64/include $ gcc -shared -o testjni.so test_TestJNI.o $ cd ..
Donc à partir de là j'ai mon .so.
Code : Sélectionner tout - Visualiser dans une fenêtre à part relocation R_X86_64_32S against `.rodata' can not be used when making a shared object; recompile with -fPIC
Je tente ensuite d'exécuter :
Même problème avec :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6 $ java -Djava.library.path=native -cp bin test.TestJNI Exception in thread "main" java.lang.UnsatisfiedLinkError: no testjni in java.library.path at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1681) at java.lang.Runtime.loadLibrary0(Runtime.java:840) at java.lang.System.loadLibrary(System.java:1047) at test.TestJNI.<clinit>(TestJNI.java:6)
(ou si je déplace mon .so à la racine du projet et que j'utilise -Djava.library.path=.)
Code : Sélectionner tout - Visualiser dans une fenêtre à part $ java -Djava.library.path="$PWD/native"
Si je remplace dans TestJNI.java la ligne :
par :
Code : Sélectionner tout - Visualiser dans une fenêtre à part System.loadLibrary("testjni");
alors ça fonctionne.
Code : Sélectionner tout - Visualiser dans une fenêtre à part System.load("/home/rom/java/TestJNI/native/testjni.so");
Qu'ai-je mal fait ?
Merci de votre aide.
Partager