Dieses Beispielprogramm soll eine in C geschriebene native
-Methode aufrufen.
Java-Code
class HelloWorld {
private native void print();
public static void main( String args[] ) {
new HelloWorld().print();
}
static {
System.loadLibrary("HelloWorld");
}
}
Nachdem ich das geschrieben hatte, kompilierte ich das Programm und erzeugte eine JNI
-Style-Header-Datei.
Die erzeugte Header-Datei lautet:
/* 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
Und die native Methode in c geschrieben
#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;
}
Der Fehler beim Kompilieren ist fatal error C1083: Cannot open include file: 'jni_md.h': No such file or directory
Auch mein Compiler unterstreicht jobject obj
und sagt this class does not have storage class or specifier
. Es unterstreicht *env
und sagt expected a ')'
.
Warum erhalte ich diesen Fehler?
Ich vermute, dass jni.h
versucht, #include <jni_md.h>
zu versuchen, was jedoch fehlschlägt, weil Sie den Pfad zum Include-Pfad nicht hinzugefügt haben.
Fügen Sie beide Einträge dem Include-Pfad Ihres C-Compilers hinzu:
C:\Program Files\Java\jdk1.7.0\include
C:\Program Files\Java\jdk1.7.0\include\win32
Der win32
-Pfad ist möglicherweise nicht erforderlich, je nachdem, wie jni.h
eingerichtet ist.
Sie sollten zunächst die folgende Header-Datei in Ihren nativen Code einfügen
#include <jni.h>
In meinem Fall in UNIX-System
Diese Headerdatei jni.h
ist unter /usr/lib/jvm/Java-8-openjdk-AMD64/include/
vorhanden.
jni_md.h
ist auch unter /usr/lib/jvm/Java-8-openjdk-AMD64/include/linux
vorhanden.
Sie können den Pfad zur Java-Installation in Ihrem System mit dem folgenden Befehl abrufen
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
dabei steht (->) für einen symbolischen Link.
Zum Schluss erhalten Sie Ihren Java-Installationspfad /usr/lib/jvm/Java-8-openjdk-AMD64/jre/bin/Java
Vergessen Sie nicht,
jni.h
&jni_md.h
-Dateipfad während. machen ihre native Compilation.
Zusammenstellung:-
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
dabei ist (-I) der Pfad.
Ausführung:-
Java -Djava.library.path=. HelloWorld
Nächster,
JNIEXPORT void JNICALL Java_HelloWorld_print( JNIEnv* env , jobject obj){
printf("Hello World!\n");
}
Sehen Sie sich nur die kleinen Änderungen an und versuchen Sie es zu implementieren.
Ich hatte dieses Problem einmal, meine Lösung bestand eigentlich darin, die interne #include von jni.h aus .__ zu bearbeiten. "jni_md.h"
an "win32/jni_md.h"
, obwohl es wahrscheinlich weniger hackig ist, wie Sie es tun sollen.
Versuche dies,
HelloWorld.c
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
Kompilieren Sie es mit cl.exe (Ich verwende VC++ und CL.EXE, wenn Sie folgende Befehlszeilenoptionen verwenden.)
c: \> cl -c/I "c:\Programme\Java\jdk1.7.0\include" /I"c:\Prog RAM-Dateien\Java\jdk1.7.0\include\win32 "HelloWorld.c
Verknüpfen Sie das .obj-Modul
c: \> link/libpath = "c:\Programme\Java\jdk1.7.0\lib" HelloWorld.obj/dll