【问题标题】:JNI - "Cannot open include file: 'jni_md.h'"JNI - “无法打开包含文件:'jni_md.h'”
【发布时间】:2011-11-04 23:50:16
【问题描述】:

此示例程序旨在调用用 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写的native方法

#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 ')'

为什么会出现这个错误?

【问题讨论】:

  • 您没有这样的文件或目录。检查?
  • @丹尼尔它在那里。 include 语句不报错
  • 你有 ,但没有“jni_md.h”。检查哪些标题包含什么;更具体地说,什么标题包括“jni_md.h”。编辑:见 Stuart Cooks 的回答。
  • @Daniel 我无法理解。
  • 请为您的问题使用更具描述性的标题

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


【解决方案1】:

我怀疑jni.h 正在尝试#include &lt;jni_md.h&gt;,但由于您尚未将其位置添加到包含路径中,因此失败了。

尝试将这两个条目添加到 C 编译器的包含路径中:

  • C:\Program Files\Java\jdk1.7.0\include
  • C:\Program Files\Java\jdk1.7.0\include\win32

win32 路径可能不是必需的,具体取决于 jni.h 的设置方式。

【讨论】:

  • 我已将C:\Program Files\Java\jdk1.7.0\include 添加到我的项目的包含目录中,然后我也得到了同样的错误
  • 这两行都添加了吗?签入jni.h,看看它如何包含jni_md.h
  • 我已经尝试了任何一种方法:添加C:\Program Files\Java\jdk1.7.0\include\Win32而不是添加路径。但这并不能解决我的问题
  • 我在 linux 上遇到了这个问题。 jni_md.h 文件位于我的 java includes/linux 文件夹中,我必须手动创建指向 include/ 文件夹的链接(快捷方式)来解决此问题。在 Windows 上,您可以尝试向该文件添加快捷方式文件。
  • 在 Mac OSX 上遇到同样的问题。文件路径为 /Library/Java/JavaVirtualMachines/jdk.jdk/Contents/Home/include/darwin/jni_md.h
【解决方案2】:

Java 中的简单 Java 本机接口 (JNI) 示例

  • 环境: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

【讨论】:

    【解决方案3】:

    试试这个,

    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:\>cl -c /I"c:\Program Files\java\jdk1.7.0\include" /I"c:\Prog ram 文件\java\jdk1.7.0\include\win32" HelloWorld.c

    链接 .obj 模块

    c:\>link /libpath="c:\Program Files\java\jdk1.7.0\lib" HelloWorld.obj /dll

    【讨论】:

    【解决方案4】:

    我曾经遇到过这个问题,我的解决方案实际上是编辑 jni.h 的内部#include from "jni_md.h""win32/jni_md.h",虽然你应该有一种不那么老套的方式。

    【讨论】:

      【解决方案5】:

      您应该首先在您的本机代码中包含以下头文件

      #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 路径的原因 Native Interface头文件jni.h在参考中提供。
      • jni.h 显式导入 jni_md.h 即。 #include "jni_md.h" 这就是为什么我们在编译中提供了对 jni_md.h 文件的下一个参考。
      • jni_md.h 包含 jbyte、jint 和 jlong​​ 的机器相关类型定义。

      执行:-

      java -Djava.library.path=. HelloWorld
      

      接下来,

      JNIEXPORT void JNICALL Java_HelloWorld_print( JNIEnv* env , jobject obj){
          printf("Hello World!\n");
      }
      

      只需查看所做的小改动并尝试实施即可。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-10
        • 2016-06-17
        • 2019-10-28
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多