ゼロから学ぶJNI:Java Native Interface

文:Peter V. Mikhalenko(special to TechRepublic)  翻訳校正:原井彰弘
2007-12-14 18:19:01
  • このエントリーをはてなブックマークに追加

 Java Native Interface(JNI)とは、Javaの1レイヤーである。JNIを用いると、Java Virtual Machine(JVM)上で動作しているJavaのコードから、CやC++、アセンブリのような他の言語で記述されたネイティブなアプリケーションやライブラリを呼び出すことが可能になる。また、逆にそれらのネイティブなコードからJavaのコードを呼び出すことも可能だ。

 JNIは、アプリケーションのコードをすべてJavaで記述することが不可能な場合に、ネイティブなメソッドを呼び出してその問題を回避する目的で使用される。具体的には、たとえばJavaの標準クラスライブラリがプラットフォーム依存の機能やプログラムライブラリをサポートしていないような場合には、JNIが用いられる。また、他の言語で書かれている既存のアプリケーションを改修し、Javaからアクセスできるようにする目的でもJNIが使用される。

 実際、ほとんどの標準クラスライブラリはJNIに依存している。たとえば、サウンド機能やファイルの読み取りなどの入出力処理は、JNIがあって初めて開発者やユーザが利用できるようになるのである。そして、このようにプラットフォーム依存でかつ高い性能が要求される機能が標準ライブラリのAPIとして実装されているおかげで、Javaのアプリケーションはプラットフォームに依存することなく安全に利用できるようになっている。従って、JNIを利用する前には、まず標準ライブラリに同様の機能がないことを確認する必要がある。この入門者向けの記事では、JNIの動作メカニズムと、ネイティブの型とJavaの型やクラスとのマッピングがどのように行われるかについて解説する。

JNIの動作メカニズム

 JNIでは、ネイティブな関数は別個の.cもしくは.cppファイルに実装される(C++の方が多少分かりやすいインタフェースを備えている)。JVMが関数を呼び出すと、JVMはJNIEnvポインタ、jobjectポインタ、Javaのメソッドで宣言された引数をその関数に渡す。以下に、JNI関数の例を挙げる。

JNIEXPORT void JNICALL Java_ClassName_MethodName
(JNIEnv *env, jobject obj)

{
//Method native implemenation


}

 上の例で用いたenvというポインタには、JVMのインタフェースが含まれている。envを用いることで、JVMと関数を通して通信が行えるようになり、Javaのオブジェクトを扱うことも可能になる。たとえば、ネイティブの配列とJavaの配列との相互変換、ネイティブの文字列とJavaの文字列との相互変換、オブジェクトの生成、例外のスローといったことは、すべてJNI関数を通して行える。Javaと比較すると相当手間が掛かる作業にはなるものの、基本的にJavaで可能なことはすべてJNIEnvを用いても行えるようになっている。

 フォーマルに述べると、ネイティブのコードがJVMの機能にアクセスするには、インタフェースポインタ(これはポインタのポインタにあたる)を通してJNI関数を呼び出す必要があるのである。ここで、このインタフェースポインタはポインタの配列を指しており、それぞれのポインタがインタフェース関数を指すというしくみになっている。そして、それぞれのインタフェース関数は、配列内の所定のオフセット位置に存在している。JNIのインタフェースポインタは、ネイティブのメソッドが呼び出される際に、引数を通して受け取るようになっている。同じJavaのスレッドからネイティブのメソッドが複数回呼び出されたときには、同じインタフェースポインタを渡すことをJVMは保証しているが、ネイティブのメソッドは異なるJavaのスレッドから呼び出される可能性もあり、その場合は異なるインタフェースポインタが渡されることもある。

 ネイティブのメソッドは、System.loadLibraryメソッドを用いてロードすることができる。以下の例では、クラスの初期化メソッドでプラットフォーム固有のネイティブライブラリをロードしている。この例では、ネイティブライブラリにはfという名前のネイティブのメソッドが定義されているという設定だ。

packagepkg;

class Cls {
native double f(int i, String s);
static {
System.loadLibrary("pkg_Cls");
}

}
  • 新着記事
  • 特集
  • ブログ
このサイトでは、利用状況の把握や広告配信などのために、Cookieなどを使用してアクセスデータを取得・利用しています。 これ以降ページを遷移した場合、Cookieなどの設定や使用に同意したことになります。
Cookieなどの設定や使用の詳細、オプトアウトについては詳細をご覧ください。
[ 閉じる ]