Javaからネイティブコード(C言語、C++等)の関数を呼ぶ場合、JNI(Java Native Interface)を使う方法があります。
今回は、JNIを使って、C++で書かれた関数を呼んでみます。 具体的には、Javaでクラス、C++でDLLを生成して、Javaのクラスから、DLLを呼ぶことになります。 Javaでは、ネイティブコードの関数と同様の型のネイティブメソッドを宣言します。 このネイティブメソッドを宣言すると、ネイティブコードの関数を、通常のメソッドのように、Javaから呼び出せるようになります。
開発環境と主な手順は、以下のようになります。
▽ 開発環境
OS: WindowsXP Professional Javaコンパイラ: Java SE Development Kit 5.0 Update 8 Cコンパイラ: Visual C++ 2005 Express Edition
▽ 主な手順
① Javaコードを書く(JniTest.java)。 ② ①のコード(JniTest.java)をコンパイルし、クラスを生成する(JniTest.class)。 更に、C++用のヘッダーファイルを生成する(JniTest.h)。 ③ ヘッダーファイル(JniTest.h)を使って、C++のコードを書く(JniTestLib.cpp)。 ④ ③のコードをコンパイルし、DLLを生成する(JniTestLib.dll)。 ⑤ ②のJavaのクラス(JniTest.class)を実行し、DLL(JniTestLib.dll)のネイティブメソッドを呼ぶ。
◆ 開発
① Javaコードを書く(JniTest.java)。
ネイティブメソッド(TestMethod)の宣言と、Java側の処理を実装します。 サンプルでは、ネイティブメソッドしか呼んでいません。
[ JniTest.java ]
public class JniTest
{
static
{
// ライブラリ(DLL)のロード
System.loadLibrary("JniTestLib");
}
// ネイティブメソッドの宣言
public native String TestMethod();
public static void main(String[] args)
{
JniTest jt = new JniTest();
// ネイティブメソッドを呼ぶ
System.out.println(jt.TestMethod());
}
}
② ①のコード(JniTest.java)をコンパイルし、クラス(JavaTest.class)を生成する。 更に、C++用のヘッダーファイル(JniTest.h)を生成する。
▽ クラス(JavaTest.class)の生成
コマンドプロンプトから、javac.exe でコンパイルします。
▽ C++用のヘッダーファイル(JniTest.h)の生成
ヘッダーの生成には、javah.exe を使い、引数には、JniTest(.class)を指定します。
以下のような内容のヘッダーが生成されます。 "JNICALL Java_JniTest_TestMethod"メソッドが、C++のDLLで実装するネイティブメソッドになります。
[ JniTest.h ]
/* DO NOT EDIT THIS FILE - it is machine generated */
#include
/* Header for class JniTest */
#ifndef _Included_JniTest
#define _Included_JniTest
#ifdef __cplusplus
extern "C" {
#endif
/*
* Class: JniTest
* Method: TestMethod
* Signature: ()Ljava/lang/String;
*/
JNIEXPORT jstring JNICALL Java_JniTest_TestMethod
(JNIEnv *, jobject);
#ifdef __cplusplus
}
#endif
#endif
③ ②のヘッダーファイル(JniTest.h)を使って、C++のコード(JniTestLib.cpp)を書く。
ここからは、Visual C++ 2005 を使います。
▽ 空のプロジェクトの作成
Visual C++ 2005 を起動し、空のプロジェクト(JniTestLib)を作成します。 Expressでは、DLLの項目がないため、ここでは、空のプロジェクトを選択します。
▽ C++ファイルの追加
作成したプロジェクトに、新規にC++ファイル(JniTestLib.cpp)を追加します。
②で生成したC++用のヘッダー(JniTest.h)をプロジェクトに追加します。
[ JniTestLib.cpp ]
#include
#include
#include "JniTest.h"
JNIEXPORT jstring JNICALL Java_JniTest_TestMethod(JNIEnv *env, jobject obj)
{
printf("DLLの Java_JniTest_TestMethod() が呼ばれました。\n");
return env->NewStringUTF("Java_JniTest_TestMethod() was completed.");
}
④ ③のコードをコンパイルし、DLLを生成する。
▽ プロジェクトのプロパティの設定
プロジェクトのプロパティを、DLL生成用に変更します。 [構成プロパティ]→[全般]→[構成の種類]を "ダイナミック ライブラリ(.dll)" に変更します。
[構成プロパティ]→[C/C++]→[全般]→[追加のインクルードディレクトリ]に、JDKのインクルードディレクトリを指定します。
[構成プロパティ]→[リンカ]→[全般]→[出力ファイル]の拡張子を、"dll"に変更します。
以上で、プロパティの設定は、完了です。
▽ DLLのビルド
ビルドし、エラーがでなければ、JniTestLib.dll が生成されます。
⑤ ②のJavaのクラス(JniTest.class)を実行し、DLL(JniTestLib.dll)のネイティブメソッドを呼ぶ。
②のJavaクラス(JniTest.class)、④のDLL(JniTestLib.dll)を同一ディレクトリにコピーします。 コマンドプロンプトから、Javaクラス(JniTest.class)を実行すると、以下のようにDLL(JniTestLib.dll)のネイティブメソッドが呼ばれます。
- 以上 -
編集履歴 [2007/05/17] 新規作成。 [2007/05/19] 前置きを少し修正。 [2008/08/29] レイアウトを修正。 [2009/01/--] サイト移転。レイアウト変更。 [2009/06/24] レイアウト変更。 [2010/03/10] サイト移転。レイアウト変更。 [2010/07/04] URL変更。 |