JNI の実装 DLL ファイルを Visual Studio .NET 2003 を使って生成するための 方法を解説します。
まずは、Java ソースとヘッダを作成します。ここでは例として、 以下のソースを用意します。
クラス名が Main、そして jniPrint というひとつのネイティブメソッドを 宣言しています。ネイティブメソッドの実装は testjni というライブラリに含みます。 Windows では、testjni.dll というライブラリファイルをロードすることになります。
ソースファイルを作成できたら、コンパイルします。
続いてネイティブで実装する必要のある関数のプロトタイプを生成します。 javah コマンドに対して、コンパイルされたクラスを指定します。-jni オプションはデフォルトの動作なので指定しなくてもかまいません。
以下のような Main.h が生成されます。Windows 環境では、自動生成される際に 改行コードが混ざっているようですが。特にそのままで問題ないでしょう。
重要なのは Java_Main_jniPrint のような Java_ で始まる関数プロトタイプです。 この関数は C 言語で実装する必要があります。
Visual Studio を起動し、新しくネイティブメソッドを実装した DLL を生成するためのプロジェクトを作成します。
Visual Studio (VC++) を起動し、 [ファイル] - [新規作成] - [プロジェクト...] を選択し、 新しくプロジェクトを作成します。
「新しいプロジェクト」ダイアログで、プロジェクトの種類として、 [VisualC++] - [Win32]、右側のテンプレートで [Win32 プロジェクト] を選択します。プロジェクト名は JNITest としておきます (ライブラリ名と同名だと、 後の手順を少し省略できます)。
下のようなダイアログが表示されるので、[アプリケーションの設定] をクリックします。
アプリケーションの設定では、アプリケーションの種類として、[DLL] を選択し、追加のオプションとして、[空のプロジェクト] を選んでおきます。
後は、[完了] をクリックすればプロジェクトの作成は完了です。
まずは、C ソースファイルを作成します。「ソリューション エクスプローラ」 に表示されているプロジェクトツリーのソースファイルのところを右クリックし、 [追加] - [新しい項目の追加...] をクリックします。
カテゴリの [コード] を選択し、[C++ ファイル] を選んで、ソースファイル名を 入力します。ここでは、test.c とします。[開く] ボタンをクリックすると、 test.c を編集するウインドウが開きます。
ここで、プロジェクトの設定をしてしまいます。 C ソースファイルを追加する前では、プロジェクトの設定で、 C/C++ に関する設定ができないようですので、このタイミングでおこないます。 メニューから[プロジェクト] - [(プロジェクト名) のプロパティ] を選択します。
まずは、JNI で使用するヘッダファイルをインクルードできるようにします。 [構成:] で、[すべての構成] を選択します。 左側に表示される構成のプロパティツリーの [C/C++] の [全般] を開き、 [追加のインクルードディレクトリ] を編集します。右側の [...] ボタンを クリックすると、新しくダイアログが立ち上がります。
先ほど javah コマンドで生成した Main.h のあるディレクトリ、 そして使用している Java 2 SDK のディレクトリにある include ディレクトリ、 さらにその中の win32 ディレクトリを追加します。追加が終われば、 [OK] をクリックします。
次に、出力ファイル名を編集します。[リンカ] - [全般] にある出力ファイル という欄を編集し、dll ファイル名を Java コード内で指定した loadLibrary() メソッドの引数にあわせて変更します。ここでは、testjni.dll です。
以上でプロジェクトの設定は完了です。[OK] をクリックして設定を完了します。
それでは、ソースを入力します。
今回はただ、printf を呼ぶだけの簡単なものです。ソースを作成できれば、 ビルドします。[ビルド] - [(プロジェクト名) のビルド] を選択してビルドします。
はじめにプロジェクトを作成したディレクトリの Debug ディレクトリに testjni.dll が生成されていることを確認します。これで出来上がりです。
それでは、実行確認してみます。生成したライブラリ testjni.dll を Main.class のあるディレクトリにコピーします。では、実行してみましょう。
"Java_Main_jniPirnt() is called." が出力されれば成功です。
補足ですが、DLL ファイルをコピーしたのは、Java VM がこの DLL ファイルを正しく見つけ出すことが可能にするためです。Windows では、DLL ファイルはパスの通ったところから探し出します。したがって、 上記コマンドを実行するフォルダに DLL をおく必要があるのです。 ためしに、カレントディレクトリを変更して Main を実行してみるとライブラリがロードできないという例外が発生するでしょう。 Main.class と testjni.dll のあるディレクトリを JNI-.net2003 として、 そのディレクトリを含むディレクトリ (JNI-.net2003 の親ディレクトリ) をカレントディレクトリとします。以下のようにしてクラスパスを指定して Main クラスを起動してください。
ライブラリをロードしようとすると、JVM は DLL ファイルを見つけられないために、 UnsatisfiedLinkError をスローします。
では、機会があれば、JNI を使ったプログラムをユーザに配布するときに どうするのがうまくいくかを見ていきたいと思います。