此示例程序用于调用用C编写的native
方法。
Java代码
class HelloWorld {
private native void print();
public static void main( String args[] ) {
new HelloWorld().print();
}
static {
System.loadLibrary("HelloWorld");
}
}
编写本文后,我编译了程序并生成了JNI
样式头文件。
生成的头文件是:
/* 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
用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;
}
我在编译时遇到的错误是fatal error C1083: Cannot open include file: 'jni_md.h': No such file or directory
我的编译器也强调jobject obj
说this class does not have storage class or specifier
。它强调*env
说expected a ')'
。
为什么我会收到此错误?
答案 0 :(得分:38)
我怀疑jni.h
正在尝试#include <jni_md.h>
,但由于您尚未将其位置添加到包含路径,因此会失败。
尝试将这两个条目添加到C编译器的包含路径中:
C:\Program Files\Java\jdk1.7.0\include
C:\Program Files\Java\jdk1.7.0\include\win32
win32
路径可能没有必要,具体取决于jni.h
的设置方式。
答案 1 :(得分:0)
试试这个,
HelloWorld.c
#include "HelloWorld.h"
#include <stdio.h>
JNIEXPORT void JNICALL Java_HelloWorld_print(JNIEnv *env, jobject obj)
{
printf("Hello World!\n");
return;
}
使用cl.exe编译它(我使用VC ++和CL.EXE命令行开关后需要。)
c:\&gt; cl -c / I“c:\ Program Files \ java \ jdk1.7.0 \ include”/ I“c:\ Prog ram Files \ java \ jdk1.7.0 \ include \ win32“HelloWorld.c
链接.obj模块
c:\&gt; link / libpath =“c:\ Program Files \ java \ jdk1.7.0 \ lib”HelloWorld.obj / dll
答案 2 :(得分:0)
我曾经遇到过这个问题,我的解决方案实际上是编辑jni.h的内部#include
"jni_md.h"
到"win32/jni_md.h"
,虽然你应该这样做的方式可能不那么简单。
答案 3 :(得分:0)
您应该首先在本机代码中包含以下头文件
#include <jni.h>
在我的UNIX系统中,
此头文件jni.h
位于/usr/lib/jvm/java-8-openjdk-amd64/include/
另外,jni_md.h
出现在/usr/lib/jvm/java-8-openjdk-amd64/include/linux
如果知道Java安装路径将您重定向到系统中的位置,则可以获取上述文件的路径。通过执行以下命令来完成它。
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
其中(->)是符号链接。
/usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
也不要忘记在添加
jni.h
和jni_md.h
文件路径时 进行本机编译。
编译:-
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
其中(-I)标识路径。
jni.h
。jni.h
进行jni_md.h
的显式导入,即。 #include "jni_md.h"
,因此我们在编译中提供了对该jni_md.h
文件的下一个引用。jni_md.h
包含与机器有关的jbyte,jint和jlong的typedef。执行:-
java -Djava.library.path=. HelloWorld
下一步,
JNIEXPORT void JNICALL Java_HelloWorld_print( JNIEnv* env , jobject obj){
printf("Hello World!\n");
}
请仅查看所做的微小更改并尝试实施。
答案 4 :(得分:0)
Java中的简单Java本机接口(JNI)示例
// Main.java
public class Main {
public native int intMethod(int i);
static {
System.loadLibrary("Main");
}
public static void main(String[] args) {
System.out.println(new Main().intMethod(2));
}
}
// Main.c:
#include "Main.h"
JNIEXPORT jint JNICALL Java_Main_intMethod(
JNIEnv *env, jobject obj, jint i)
{
return i * i;
}
编译并运行:
javac Main.java -h .
gcc -dynamiclib -O3 \
-I/usr/include \
-I$JAVA_HOME/include \
-I$JAVA_HOME/include/darwin \
Main.c -o libMain.dylib
java -cp . -Djava.library.path=$(pwd) Main
输出:
4
答案 5 :(得分:-2)
只需将jni_md.h文件复制到jni.h所在的文件夹即可。