web-dev-qa-db-ja.com

JNI-「インクルードファイルを開けません: 'jni_md.h'」

このサンプルプログラムは、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。下線*envexpected a ')'

なぜこのエラーが発生するのですか?

35
Suhail Gupta

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がセットアップされます。

39
Stuart Cook

最初にネイティブコードに次のヘッダーファイルを含める必要があります

#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 header file 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");
}

行われた小さな変更を確認し、実装してみてください。

0
Yash Karanje

一度この問題がありました。私の解決策は、実際にはjni.hの内部#includeを"jni_md.h"から"win32/jni_md.h"に編集することでした。

0
Zannith

これを試して、

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 Files\Java\jdk1.7.0\include\win32" HelloWorld.c

.objモジュールのリンク

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

0
adatapost