JNI - «Не удается открыть включаемый файл:« jni_md.h »» - PullRequest
34 голосов
/ 27 августа 2011

Этот пример программы предназначен для вызова метода native, написанного на C.

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

Почему я получаю эту ошибку?

Ответы [ 5 ]

38 голосов
/ 27 августа 2011

Я подозреваю, что jni.h пытается #include <jni_md.h>, который затем завершается ошибкой, потому что вы не добавили его местоположение в ваш путь включения.

Попробуйте добавить обе эти записи в include вашего компилятора Cпуть:

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

Путь win32 может быть необязательным в зависимости от настройки jni.hдо.

0 голосов
/ 28 января 2019

Вы должны сначала включить следующий файл заголовка в свой собственный код

#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.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) - Идентифицировать путь.

  • Выше команда компилирует наш собственный код, и поэтому путь кЗаголовочный файл нативного интерфейса Java 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");
}

Просто посмотрите на сделанные небольшие изменения и попробуйте их реализовать.

0 голосов
/ 21 июня 2017

Однажды у меня была эта проблема, мое решение было на самом деле отредактировать внутренний #include в jni.h со "jni_md.h" до "win32/jni_md.h", хотя, вероятно, есть и менее хакерский способ сделать это.

0 голосов
/ 03 сентября 2015

Просто скопируйте файл jni_md.h в папку, где находится jni.h.

0 голосов
/ 27 августа 2011

Попробуйте,

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: \ Prom ram Files \ java \ jdk1.7.0 \ include \ win32"HelloWorld.c

Модуль Link .obj

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

...