Java呼び出しC言語JNIライブラリ(Hello Worldインスタンス)


Javaでc言語のライブラリを呼び出すには、ずっと不思議に思っていましたが、JavaがJNIというものを提供してくれたことも可能になりました.私たちとして、最も簡単なHello Worldから始めましょう.
まず、私たちがしたいことを話します.c言語でvoid sayHello()関数を定義します(Hello Worldを印刷します).そしてJavaでこの関数を呼び出してHello Wordを表示します.
JavaとC言語の2つの部分から説明します.
1. Java  ぶぶん
まず、sayHello関数を明示するHelloNativeを定義します.関数はNativeタイプであることを明示します.以下のようにします.
public class HelloNative {

    public native void sayHello();

}

このクラスをコンパイルしてclassファイルを生成します.
javac HelloWorld.java

Javahによる必要なhファイルの生成
javah HelloNative

生成されたhファイルは、次のようになります.
/* DO NOT EDIT THIS FILE - it is machine generated */

#include <jni.h>

/* Header for class HelloNative */



#ifndef _Included_HelloNative

#define _Included_HelloNative

#ifdef __cplusplus

extern "C" {

#endif

/*

 * Class:     HelloNative

 * Method:    sayHello

 * Signature: ()V

 */

JNIEXPORT void JNICALL Java_HelloNative_sayHello

  (JNIEnv *, jobject);



#ifdef __cplusplus

}

#endif

#endif

上の自動生成プログラムを見てもいいです.プログラムincludeはjni.hです.このヘッダファイルは$JAVA_です.HOMEの下のincludeフォルダの下で.また生成した関数名が我々の関数名の前にJavaを付けたことを発見することができる.HelloNative.
2.C言語部分
上で生成したhファイルに基づいて、HelloNative.cppを作成してHello Worldを表示する関数を実現するように、対応するコード実装を作成します.以下のようにします.
#include <stdio.h>

#include "HelloNative.h"



JNIEXPORT void JNICALL Java_HelloNative_sayHello(JNIEnv *, jobject)

{

    printf("Hello World!
"); }

コードの作成が完了した後、gccでライブラリファイルにコンパイルし、コマンドは以下の通りです.
gcc -fPIC -I/usr/lib/jvm/java-7-openjdk-i386/include -I/usr/lib/jvm/java-7-openjdk-i386/include/linux -shared -o libHelloNative.so HelloNative.cpp 

これにより、現在のディレクトリの下にlibHelloNative.soのライブラリファイルが生成されます.このとき、必要なライブラリは生成され、C言語での作業は完了しました.
次に、Javaでプログラムを作成してテストする必要があります.プログラムの前に、ライブラリをロードする必要があります.ロード方法はJavaを呼び出すことです. System.loadLibrary("HelloNative"); 
public class TestNative 

{

    static {

        try { 

            System.loadLibrary("HelloNative"); 

        } 

        catch(UnsatisfiedLinkError e) { 

            System.out.println( "Cannot load hello library:
" + e.toString() ); } } public static void main(String[] args) { HelloNative test = new HelloNative(); test.sayHello(); } }

しかし、コンパイル後、実行中に問題が発生しました.
Cannot load hello library:

 java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path

Exception in thread "main" java.lang.UnsatisfiedLinkError: HelloNative.sayHello()V

    at HelloNative.sayHello(Native Method)

    at TestNative.main(TestNative.java:13)

ライブラリの読み込みに失敗しましたが、私たちのライブラリは現在のフォルダの下にあるのに、どうして読み込みに失敗しましたか?
System.getProperty(「java.library.path」)で見ると、java.library.pathには現在のディレクトリが存在しないことがわかります.主に以下の解決策があります.
1)生成されたライブラリをjava.library.pathのあるパスにコピーするのは、もちろんよくありません.
2)環境変数export LD_の設定LIBRARY_PATH=.:$LD_LIBRARY_PATH、現在のディレクトリをLD_に追加LIBRARY_PATH中
3)javaのオプションを設定し、現在のディレクトリを追加します.java-Djava.library.path=.$LD_LIBRARY_PATH
これで私たちのプログラムは成功して実行できます.表示されている「Hello World!」が見えます.