ゼロから学ぶJNI:Java Native Interface
翻訳校正:原井彰弘
JNIの動作メカニズムと、ネイティブの型とJavaの型やクラスとのマッピングがどのように行われるかについて解説する。
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");
}
}
- ホワイトペーパー
- 話題のタグ
グーグル、JavaScriptプログラミングツールをリリース
Windowsの歴史 Windows Server 2008編:同じカーネルを持つ「Vista」とは対照的に早くから支持を得たサーバOS
Windowsの歴史 Windows Server 2003 R2編:安定性と先進性の両立目指す「R2」の先駆けとなったOS
モジラ、「Firefox 3.6」の第1ベータ版をリリース
―エン・ジャパン厳選求人☆毎週更新―
【最終警告】パンデミック対策特集
100万円で実現!中小企業の情報漏えい対策
最大32個のセンサーが電力を徹底管理!
進むストレージ環境の見直し
大丈夫?あなたの会社のセキュリティ対策
企業ITシステムの企画、構築、運用のイロハ