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
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.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
/* 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
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
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:
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
... j'ai plutôt fait:
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"
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
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
Je ne sais pas où se situe mon erreur... est-ce dans la ligne de commande de compilation, dans la configuration des mes PATHS..?

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