ゼロから学ぶJNI:Java Native Interface

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

 System.loadLibraryメソッドの引数はライブラリの名前であり、これはプログラマが自由に設定できる。この名前はプラットフォーム固有の標準的な方法で、ネイティブライブラリの名前に変換される。たとえば、Solarisでは「pkg_Cls」という名前は「libpkg_Cls.so」に変換される。また、Win32システムの場合は、同じ「pkg_Cls」という名前は「pkg_Cls.dll」と変換される。

 一方、エントリの名前は、動的リンカがJavaのコードを元に決定する。ネイティブメソッドの名前は、「接頭辞『Java_』」「マングルされた(mangled)完全修飾クラス名」「マングルされたメソッド名」を並べたものになる。

 補足:MicrosoftのJVMの実装では、Raw Native Interface(RNI)と呼ばれる類似のメカニズムによって、ネイティブのWindowsコードをJavaから呼び出している。

データ型のマッピング

 整数や文字のようなプリミティブ型は、値のコピーによってJavaとネイティブコードで受け渡しが行われる。一方、Javaのオブジェクトは参照によって渡される。

 この表は、Javaの型とネイティブの型との対応を示している。これらの型は相互に代替が可能であるため、たとえば普通int型を使う場面でjint型を使ったり、その逆を行ったりということができる。その際に、型のキャストは一切必要ない。しかし、Javaの文字列、配列とネイティブの文字列、配列に関しては、同じ方法で扱ってはいけない。たとえば、char *が必要とされる場面でjstringを用いると、JVMがクラッシュする可能性もあるのだ。次の例では、文字列の正しい扱い方を示す。

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

{
//Get the native string from Java string
const char *nativeString = env->GetStringUTFChars(env, javaString, 0);
printf("%s", nativeString);
env->ReleaseStringUTFChars(env, javaString, nativeString);

}

 このように、Javaオブジェクトを操作するには、常にインタフェースポインタenvを用いる必要があるのである。

まとめ

 JNIを利用したアプリケーションは簡単には作成できない。しかし、パフォーマンスが向上したり、レガシーコードをそのまま利用できるようになったり、あるいはプラットフォーム固有の機能を利用した機能を追加できるようになったりというように、JNIを利用することによって得られるメリットも多い。

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