Variousible ホーム 暫定 じゃばるーむ トップ

JNI with Microsoft Visual Studio .NET 2003

2004/02/08

JNI の実装 DLL ファイルを Visual Studio .NET 2003 を使って生成するための 方法を解説します。

Java ソースの作成とヘッダの生成

まずは、Java ソースとヘッダを作成します。ここでは例として、 以下のソースを用意します。

Main.java
public class Main { static { System.loadLibrary("testjni"); } public Main() { } public native void jniPrint(); public static void main(String[] args) { new Main().jniPrint(); } }

クラス名が Main、そして jniPrint というひとつのネイティブメソッドを 宣言しています。ネイティブメソッドの実装は testjni というライブラリに含みます。 Windows では、testjni.dll というライブラリファイルをロードすることになります。

ソースファイルを作成できたら、コンパイルします。

> javac Main.java

続いてネイティブで実装する必要のある関数のプロトタイプを生成します。 javah コマンドに対して、コンパイルされたクラスを指定します。-jni オプションはデフォルトの動作なので指定しなくてもかまいません。

> javah -jni Main

以下のような Main.h が生成されます。Windows 環境では、自動生成される際に 改行コードが混ざっているようですが。特にそのままで問題ないでしょう。

Main.h
/* DO NOT EDIT THIS FILE - it is machine generated */ #include <jni.h> /* Header for class Main */ #ifndef _Included_Main #define _Included_Main #ifdef __cplusplus extern "C" { #endif /* * Class: Main * Method: jniPrint * Signature: ()V */ JNIEXPORT void JNICALL Java_Main_jniPrint (JNIEnv *, jobject); #ifdef __cplusplus } #endif #endif

重要なのは Java_Main_jniPrint のような Java_ で始まる関数プロトタイプです。 この関数は C 言語で実装する必要があります。

DLL プロジェクトの作成

Visual Studio を起動し、新しくネイティブメソッドを実装した DLL を生成するためのプロジェクトを作成します。

Visual Studio (VC++) を起動し、 [ファイル] - [新規作成] - [プロジェクト...] を選択し、 新しくプロジェクトを作成します。

プロジェクトの作成

「新しいプロジェクト」ダイアログで、プロジェクトの種類として、 [VisualC++] - [Win32]、右側のテンプレートで [Win32 プロジェクト] を選択します。プロジェクト名は JNITest としておきます (ライブラリ名と同名だと、 後の手順を少し省略できます)。

下のようなダイアログが表示されるので、[アプリケーションの設定] をクリックします。

アプリケーションの設定

アプリケーションの設定では、アプリケーションの種類として、[DLL] を選択し、追加のオプションとして、[空のプロジェクト] を選んでおきます。

アプリケーションウィザード

後は、[完了] をクリックすればプロジェクトの作成は完了です。

設定とファイルの追加

まずは、C ソースファイルを作成します。「ソリューション エクスプローラ」 に表示されているプロジェクトツリーのソースファイルのところを右クリックし、 [追加] - [新しい項目の追加...] をクリックします。

カテゴリの [コード] を選択し、[C++ ファイル] を選んで、ソースファイル名を 入力します。ここでは、test.c とします。[開く] ボタンをクリックすると、 test.c を編集するウインドウが開きます。

ここで、プロジェクトの設定をしてしまいます。 C ソースファイルを追加する前では、プロジェクトの設定で、 C/C++ に関する設定ができないようですので、このタイミングでおこないます。 メニューから[プロジェクト] - [(プロジェクト名) のプロパティ] を選択します。

C/C++ 全般の設定

まずは、JNI で使用するヘッダファイルをインクルードできるようにします。 [構成:] で、[すべての構成] を選択します。 左側に表示される構成のプロパティツリーの [C/C++] の [全般] を開き、 [追加のインクルードディレクトリ] を編集します。右側の [...] ボタンを クリックすると、新しくダイアログが立ち上がります。

インクルードディレクトリの追加

先ほど javah コマンドで生成した Main.h のあるディレクトリ、 そして使用している Java 2 SDK のディレクトリにある include ディレクトリ、 さらにその中の win32 ディレクトリを追加します。追加が終われば、 [OK] をクリックします。

次に、出力ファイル名を編集します。[リンカ] - [全般] にある出力ファイル という欄を編集し、dll ファイル名を Java コード内で指定した loadLibrary() メソッドの引数にあわせて変更します。ここでは、testjni.dll です。

出力ファイルの指定

以上でプロジェクトの設定は完了です。[OK] をクリックして設定を完了します。

ソースの作成とビルド

それでは、ソースを入力します。

test.c
#include <stdio.h> #include <jni.h> #include "Main.h" JNIEXPORT void JNICALL Java_Main_jniPrint(JNIEnv *env, jobject obj) { printf("Java_Main_jniPrint() is called.\n"); }

今回はただ、printf を呼ぶだけの簡単なものです。ソースを作成できれば、 ビルドします。[ビルド] - [(プロジェクト名) のビルド] を選択してビルドします。

はじめにプロジェクトを作成したディレクトリの Debug ディレクトリに testjni.dll が生成されていることを確認します。これで出来上がりです。

実行確認

それでは、実行確認してみます。生成したライブラリ testjni.dll を Main.class のあるディレクトリにコピーします。では、実行してみましょう。

> java Main

"Java_Main_jniPirnt() is called." が出力されれば成功です。

補足ですが、DLL ファイルをコピーしたのは、Java VM がこの DLL ファイルを正しく見つけ出すことが可能にするためです。Windows では、DLL ファイルはパスの通ったところから探し出します。したがって、 上記コマンドを実行するフォルダに DLL をおく必要があるのです。 ためしに、カレントディレクトリを変更して Main を実行してみるとライブラリがロードできないという例外が発生するでしょう。 Main.class と testjni.dll のあるディレクトリを JNI-.net2003 として、 そのディレクトリを含むディレクトリ (JNI-.net2003 の親ディレクトリ) をカレントディレクトリとします。以下のようにしてクラスパスを指定して Main クラスを起動してください。

> java -classpath JNI-.net2003 Main

ライブラリをロードしようとすると、JVM は DLL ファイルを見つけられないために、 UnsatisfiedLinkError をスローします。

では、機会があれば、JNI を使ったプログラムをユーザに配布するときに どうするのがうまくいくかを見ていきたいと思います。

Variousible ホーム 暫定 じゃばるーむ トップ
※Java およびすべての Java に関する標章は、米国およびその他の国における米国 Sun Microsystems, Inc. の商標または登録商標です。
※その他の登場する製品名は、各社の商標または登録商標です。
本サイトについて
Copyright © 2004 KURIHARA, Yusuke