Cet exemple de programme est destiné à appeler une méthode native
écrite en C.
Java Code
class HelloWorld {
private native void print();
public static void main( String args[] ) {
new HelloWorld().print();
}
static {
System.loadLibrary("HelloWorld");
}
}
Après avoir écrit ceci, j’ai compilé le programme et généré un fichier d’en-tête de style JNI
.
Le fichier d'en-tête généré est:
/* DO NOT EDIT THIS FILE - it is machine generated */
#include <C:\Program Files\Java\jdk1.7.0\include\jni.h>
/* Header for class HelloWorld */
#ifndef _Included_HelloWorld
#define _Included_HelloWorld
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: HelloWorld
* Method: print
* Signature: ()V
*/
JNIEXPORT void JNICALL Java_HelloWorld_print
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
Et la méthode native écrite en c
#include <C:\Program Files\Java\jdk1.7.0\include\jni.h>
#include <C:\Program Files\Java\jdk1.7.0\include\win32\jni_md.h>
#include <stdio.h>
#include "HelloWorld.h"
JNIEXPORT void JNICALL Java_HelloWorld_print( JNIENv *env , jobject obj) {
printf("Hello World!\n");
return;
}
L'erreur que j'ai lors de la compilation est fatal error C1083: Cannot open include file: 'jni_md.h': No such file or directory
De plus, mon compilateur souligne jobject obj
en disant que this class does not have storage class or specifier
. Il souligne *env
en disant expected a ')'
.
Pourquoi ai-je cette erreur?
Je soupçonne que jni.h
essaye de #include <jni_md.h>
, ce qui échoue ensuite car vous n'avez pas ajouté son emplacement à votre chemin d'inclusion.
Essayez d’ajouter ces deux entrées au chemin d’inclusion de votre compilateur C:
C:\Program Files\Java\jdk1.7.0\include
C:\Program Files\Java\jdk1.7.0\include\win32
Le chemin d'accès win32
peut ne pas être nécessaire, selon la configuration de jni.h
.
Vous devez d'abord inclure le fichier d'en-tête suivant dans votre code natif
#include <jni.h>
Dans mon cas sous UNIX,
Ce fichier d'en-tête jni.h
est présent à /usr/lib/jvm/Java-8-openjdk-AMD64/include/
De plus, jni_md.h
est présent à /usr/lib/jvm/Java-8-openjdk-AMD64/include/linux
Vous pouvez obtenir le chemin d'accès à l'installation Java sur votre système à l'aide de la commande suivante
whereis Java
/usr/bin/Java /usr/share/Java /usr/share/man/man1/Java.1.gz
ls -l /usr/bin/Java
/usr/bin/Java -> /etc/alternatives/Java
ls -l /etc/alternatives/Java
/etc/alternatives/Java -> /usr/lib/jvm/Java-8-openjdk-AMD64/jre/bin/Java
où (->) est un lien symbolique.
Enfin, vous obtenez votre chemin d'installation Java /usr/lib/jvm/Java-8-openjdk-AMD64/jre/bin/Java
N'oubliez pas non plus d'inclure les fichiers
jni.h
etjni_md.h
pendant que faire leur compilation native.
Compilation:-
gcc -I /usr/lib/jvm/Java-8-openjdk-AMD64/include/ -I /usr/lib/jvm/Java-8-openjdk-AMD64/include/linux/ -o libHelloWorld.so -shared *nativeSourceCodeFile*.c
où (-I) est Identifier le chemin.
Exécution:-
Java -Djava.library.path=. HelloWorld
Suivant,
JNIEXPORT void JNICALL Java_HelloWorld_print( JNIEnv* env , jobject obj){
printf("Hello World!\n");
}
Il suffit de voir les petites modifications apportées et d'essayer de la mettre en œuvre.
J'ai eu ce problème une fois, ma solution était en fait de modifier le #include interne de jni.h à partir de "jni_md.h"
à "win32/jni_md.h"
, bien qu'il y ait probablement une manière moins astucieuse de le faire.
Essaye ça,
HelloWorld.c
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
Compilez-le à l'aide de cl.exe (j'utilise VC++ et CL.EXE, mais vous devez suivre les commutateurs de ligne de commande.)
c: \> cl -c/I "c:\Programmes\Java\jdk1.7.0\include" /I"c:\Prog Fichiers ram\Java\jdk1.7.0\include\win32 "HelloWorld.c
Link .obj module
c: \> link/libpath = "c:\Program Files\Java\jdk1.7.0\lib" HelloWorld.obj/dll