JNI - “无法打开包含文件:'jni_md.h'”

时间:2011-08-27 06:51:47

标签: java c compiler-errors java-native-interface

此示例程序用于调用用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 objthis class does not have storage class or specifier。它强调*envexpected a ')'

为什么我会收到此错误?

6 个答案:

答案 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

其中(->)是符号链接。

  • 最后,您获得了Java安装路径。就我而言 /usr/lib/jvm/java-8-openjdk-amd64/jre/bin/java
  

也不要忘记在添加jni.hjni_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)标识路径。

  • 以上命令编译了我们的本机代码,这就是Java路径的原因 参考中提供了本机接口头文件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)示例

  • env: jdk8,macOS 10.15
// 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所在的文件夹即可。