Echec lors du didacticiel JNI de Java
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:
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:
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:
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:
1 2 3
| cl -Ic:/jdk1.2/include
-Ic:/jdk1.2/include/win32
-LD nativelib.c -Felibnative.dll |
... j'ai plutôt fait:
Code:
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:
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