Bonjour,
En cherchant sur le net un guide pour apprendre JNI, je suis tombé sur une page officielle de JAVA. Je ne pouvais pas rêver mieux, donc...
http://java.sun.com/developer/online.../jniexamp.html
Le tuto décrit un programme qui lit le contenu d'un fichier et l'affiche dans la console.
La lecture du fichier est fait en C, et l'affichage, et JAVA.
Le guide me dit de créer 3 fichiers: ReadFile.java, Readfile.h (généré par javah), et Readfile.cpp
Readfile.java
ReadFile.h
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31 import java.util.*; public class ReadFile { //Native method declaration native byte[] loadFile( String name ); //Load the library static { System.loadLibrary( "nativelib" ); } public static void main( String args[] ) { byte buf[]; // Create class instance ReadFile mappedFile = new ReadFile(); // Call native method to load ReadFile.java buf = mappedFile.loadFile( "ReadFile.java" ); //Print contents of ReadFile.java for( int i=0;i < buf.length;i++ ) { System.out.print( (char)buf[ i ] ); } } }
ReadFile.cpp
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
17
18
19
20
21
22
23
24
25
26 /* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class ReadFile */ #ifndef _Included_ReadFile #define _Included_ReadFile #ifdef __cplusplus extern "C" { #endif /* * Class: ReadFile * Method: loadFile * Signature: (Ljava/lang/String;)[B */ JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile( JNIEnv*, jobject, jstring ); #ifdef __cplusplus } #endif #endif
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66 #include <jni.h> #include <sys/types.h> #include <sys/ipc.h> #include <sys/shm.h> #include <sys/mman.h> #include <sys/stat.h> #include <fcntl.h> #include <unistd.h> JNIEXPORT jbyteArray JNICALL Java_ReadFile_loadFile( JNIEnv* env, jobject jobj, jstring name ) { caddr_t m; jbyteArray jb; jboolean iscopy; struct stat finfo; const char *mfile = (*env)->GetStringUTFChars( env, name, &iscopy ); int fd = open( mfile, O_RDONLY ); if( fd == -1 ) { printf( "Could not open %s\n", mfile ); } lstat( mfile, &finfo ); m = mmap( (caddr_t) 0, finfo.st_size, PROT_READ, MAP_PRIVATE, fd, 0 ); if( m == (caddr_t) - 1 ) { printf( "Could not mmap %s\n", mfile ); return( 0 ); } jb = (*env)->NewByteArray( env, finfo.st_size); (*env)->SetByteArrayRegion( env, jb, 0, finfo.st_size, (jbyte *)m ); close( fd ); (*env)->ReleaseStringUTFChars( env, name, mfile ); return ( jb ); }
J'ai installé MinGW sur Windows, et je dispose de GCC.
Donc, à la commande:
... j'ai plutôt fait:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3 cl -Ic:/jdk1.2/include -Ic:/jdk1.2/include/win32 -LD nativelib.c -Felibnative.dll
là-dessus, la console m'affiche des centaines de pages d'erreurs. Voici la fin, pour vous donnez une idée.
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2 gcc -Wall -shared ReadFile.cpp -o nativelib.dll -I"c:\Program Files\Java\jdk1.6.0_11\include" -I"c:\Program Fil es\Java\jdk1.6.0_11\include" -L"c:\Program Files\Java\jdk1.6.0_11\lib"
Je ne sais pas où se situe mon erreur... est-ce dans la ligne de commande de compilation, dans la configuration des mes PATHS..?
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
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60 ... ... c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1822: error: 'const struct JNINativeInterface_' has no member named 'DeleteWeakGlobalRef' c:/Program Files/Java/jdk1.6.0_11/include/jni.h: In member function `jboolean JNIEnv_::ExceptionCheck()': c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1826: error: 'const struct JNINativeInterface_' has no member named 'ExceptionCheck' c:/Program Files/Java/jdk1.6.0_11/include/jni.h: In member function `_jobject* JNIEnv_::NewDirectByteBuffer(void*, int)': c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1830: error: 'const struct JNINativeInterface_' has no member named 'NewDirectByteBuffer' c:/Program Files/Java/jdk1.6.0_11/include/jni.h: In member function `void* JNIEnv_::GetDirectBufferAddress(_jobject*)': c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1833: error: 'const struct JNINativeInterface_' has no member named 'GetDirectBufferAddress' c:/Program Files/Java/jdk1.6.0_11/include/jni.h: In member function `jobjectRefType JNIEnv_::GetObjectRefType(_jobject*)': c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1839: error: 'const struct JNINativeInterface_' has no member named 'GetObjectRefType' c:/Program Files/Java/jdk1.6.0_11/include/jni.h: At global scope: c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1851: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1853: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1859: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1877: error: `JNICALL' has not been declared c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1877: error: ISO C++ forbids declaration of `jint' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1877: error: `jint' declared as function returning a function c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1877: error: ISO C++ forbids declaration of `DestroyJavaVM' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1879: error: `JNICALL' has not been declared c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1879: error: ISO C++ forbids declaration of `jint' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1879: error: `jint' declared as function returning a function c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1879: error: ISO C++ forbids declaration of `AttachCurrentThread' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1879: error: `int JNIInvokeInterface_::jint(int*)' and `int JNIInvokeInterface_::jint(int*)' cannot be overloaded c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1881: error: `JNICALL' has not been declared c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1881: error: ISO C++ forbids declaration of `jint' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1881: error: `jint' declared as function returning a function c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1881: error: ISO C++ forbids declaration of `DetachCurrentThread' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1881: error: `int JNIInvokeInterface_::jint(int*)' and `int JNIInvokeInterface_::jint(int*)' cannot be overloaded c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: `JNICALL' has not been declared c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: `jint' is not a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: ISO C++ forbids declaration of `jint' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: ISO C++ forbids declaration of `version' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: `jint' declared as function returning a function c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: ISO C++ forbids declaration of `GetEnv' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1883: error: `int JNIInvokeInterface_::jint(int*)' and `int JNIInvokeInterface_::jint(int*)' cannot be overloaded c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1885: error: `JNICALL' has not been declared c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1885: error: ISO C++ forbids declaration of `jint' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1885: error: `jint' declared as function returning a function c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1885: error: ISO C++ forbids declaration of `AttachCurrentThreadAsDaemon' with no type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1885: error: `int JNIInvokeInterface_::jint(int*)' and `int JNIInvokeInterface_::jint(int*)' cannot be overloaded c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1892: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1895: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1898: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1902: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1905: error: `jint' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1916: error: `JNIIMPORT' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1919: error: `JNIIMPORT' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1922: error: `JNIIMPORT' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1926: error: `JNIEXPORT' does not name a type c:/Program Files/Java/jdk1.6.0_11/include/jni.h:1929: error: expected constructor, destructor, or type conversion before "void" ReadFile.cpp:3:21: sys/ipc.h: No such file or directory ReadFile.cpp:4:21: sys/shm.h: No such file or directory ReadFile.cpp:5:22: sys/mman.h: No such file or directory ReadFile.cpp:10: error: `JNIEXPORT' does not name a type
Ce doit être une erreur facile à régler pour qui a déjà travaillé avec JNI.
Dans le cas où un expert JNI passerait dans les parages, j'aimerais lui demander ce qui, selon lui, vaut la peine d'être externalisé dans un code C/C++, et ce qui n'en vaut pas la peine.
Merciiiii
Partager