Java Native Interface
基本的には、Javaコードでできることは全てJNIEnvを用いて行うことができる。
以下の例ではJava文字列をネイティブな文字列に変換し、C/C++の標準ライブラリを利用して標準出力に出力する。
上記のようにしてCまたはC++で記述した関数が myjni ライブラリモジュールに実装されていると仮定し、Javaプログラムから呼び出す例を示す。C/C++側の実装関数とJava側のメソッドバインディングは実行時に動的に解決される。
オブジェクト指向言語であるC++に対しては、Cよりも多少洗練されたJNI APIが提供される。C++ではJavaのように、オブジェクトのメソッド(メンバー関数)という概念と、メソッド呼び出しのセマンティクス(意味)を表現するシンタックス(構文)を持つため、C++のJNIコードはCのそれに比べて構文的に多少簡潔である。
Cではenvパラメータは(*env)->でデリファレンスされ、さらにenvパラメータは明示的にJNIEnvのメソッドに渡されなければならない。
C++ではenvパラメータはenv->でデリファレンスされるが、envパラメータはオブジェクトのメソッド呼び出しセマンティクスの一部として暗黙的に渡される。
以降のコード例では、断りがない限りC++を前提とするものとする。
一部のネイティブデータ型とJavaデータ型はそれぞれ相互変換をすることができる。オブジェクトや配列、文字列などの合成型のために、ネイティブコードはJNIEnvのメソッド呼び出しにおいて、明示的なデータの変換を行う必要がある。
以下の表ではJavaとネイティブ間のデータ型のマッピングを示す。C/C++の型は<jni.h>ヘッダーにてtypedefにより定義されたエイリアスであり、実装は処理系依存である。
JNIでJavaの型を識別する概念として、「型シグネチャ」が定義されている。
"L fully-qualified-class ;"というシグネチャは名前によって一意に識別されるJavaクラスを意味する。 例えば文字列"Ljava/lang/String;"はクラスjava.lang.Stringを意味する。また、接頭辞[はその型の配列を意味する。例えば、[IはJavaにおけるint型の配列すなわちint[]に相当する。
表中の対応する型同士は暗黙的に相互変換可能である。実際の変換はJNIレイヤーが担う。プログラマーは型キャスト無しで、Javaのint型と同様にjintを使用することができる。jint型からJavaのint型への変換も同様である。
なお、jstringはJavaのString型への間接参照であり、C/C++のポインタ型char*とは無関係である。