JNI バージョン 1.4 では、JNI 呼び出しインタフェースの新しいエントリポイントのほか、java.nio
パッケージのサポートが追加されました。また、JNI バージョン番号が上がったことに伴って JNI_OnLoad
の解説が更新されました。
新しい呼び出しインタフェースルーチンによって、ネイティブコードが Java 仮想マシン (JVM) にデーモンスレッドを接続できます。これは、このスレッドがシャットダウン時に終了するのを JVM が待つべきではない場合に便利です。
NIO 関連のエントリポイントにより、ネイティブコードが java.nio
直接バッファーにアクセスできます。直接バッファーのコンテンツは、通常のガベージコレクトされたヒープの外側の、ネイティブメモリー内に格納できます。直接バッファーについては、New I/O API および java.nio.ByteBuffer クラスの仕様を参照してください。
Java 仮想マシンの各実装ではこれらの関数をサポートする必要がありますが、すべての実装が直接バッファーへの JNI のアクセスをサポートする必要はありません。JVM がこのようなアクセスをサポートしない場合は、NewDirectByteBuffer および GetDirectBufferAddress 関数は常に NULL を返し、GetDirectBufferCapacity 関数は常に -1 を返します。JVM がこのようなアクセスをサポートする場合、これら 3 つの関数は適切な値を返すように実装される必要があります。
JNI のバージョン番号が上がりました。インクルードファイル jni.h
では、新しい定数を定義しています。
#define JNI_VERSION_1_4 0x00010004
GetVersion
プロシージャーは現在この値を返し、JNI_OnLoad
プロシージャーの仕様が改訂されています。
jint JNI_OnLoad(JavaVM *vm, void *reserved); The VM calls JNI_OnLoad when the native library is loaded (for example, through System.loadLibrary). JNI_OnLoad must return the JNI version needed by the native library. In order to use the JNI functions introduced in J2SE release 1.2 in addition to those that were available in JDK 1.1, a native library must export a JNI_OnLoad function that returns JNI_VERSION_1_2. In order to use the JNI functions introduced in J2SE release 1.4 in addition to those that were available in release 1.2, a native library must export a JNI_OnLoad function that returns JNI_VERSION_1_4. If the native library does not export a JNI_OnLoad function, the VM assumes that the library only requires JNI version JNI_VERSION_1_1. If the VM does not recognize the version number returned by JNI_OnLoad, the native library cannot be loaded.
jint AttachCurrentThreadAsDaemon(JavaVM* vm, void** penv, void* args);
AttachCurrentThread とセマンティクスは同じですが、新しく作成された java.lang.Thread インスタンスはデーモンです。
スレッドがすでに AttachCurrentThread または AttachCurrentThreadAsDaemon を介して接続されている場合、このルーチンは、penv が指している値を現在のスレッドの JNIEnv に設定します。この場合、AttachCurrentThread もこのルーチンも、スレッドのデーモンステータスに影響しません。
JavaVM
インタフェース関数テーブルのインデックス 7。
vm: 現在のスレッドが接続される仮想マシンインスタンス。
penv: 現在のスレッドの JNIEnv インタフェースポインタが配置される位置へのポインタ。
args: JavaVMAttachArgs 構造体へのポインタ。
成功した場合は 0、失敗した場合は負の数を返します。
なし。
jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);
メモリーアドレス address から始まる capacity バイトまでのメモリーブロックを参照する直接バッファー java.nio.ByteBuffer を割り当てて返します。
この関数を呼び出して、Java レベルのコードに最終的なバイトバッファーのオブジェクトを返すネイティブコードは、そのバッファーが、読み込みと、適切な場合には書き出しのアクセスが可能な、有効なメモリー領域を参照する必要があります。Java コードから無効なメモリー位置にアクセスしようとすると、視覚効果のない任意の値を返すか、指定されていない例外が発生します。
JNIEnv
インタフェース関数テーブルのインデックス 229。
env: JNIEnv インタフェースポインタ
address: メモリー領域の開始アドレス (NULL は不可)
capacity: メモリー領域のバイト数で示したサイズ (正の数であること)
新規にインスタンス化された java.nio.ByteBuffer オブジェクトのローカル参照を返します。例外が発生したり、この仮想マシンが、直接バッファーへの JNI のアクセスをサポートしていない場合は、NULL を返します。
OutOfMemoryError:ByteBuffer オブジェクトの割り当てに失敗した場合
void* GetDirectBufferAddress(JNIEnv* env, jobject buf);
指定された直接バッファー java.nio.Buffer によって参照されるメモリー領域の開始アドレスをフェッチし、返します。
この関数によって、ネイティブコードは、Java コードがバッファーオブジェクトを介してアクセスできるメモリー領域と同じメモリー領域にアクセスできるようになります。
JNIEnv
インタフェース関数テーブルのインデックス 230。
env: JNIEnv インタフェースポインタ
buf: 直接バッファー java.nio.Buffer オブジェクト (NULL は不可)
バッファーに参照されるメモリー領域の開始アドレスを返します。メモリー領域が未定義の場合、指定されたオブジェクトが直接バッファー java.nio.Buffer でない場合、または、直接バッファーへの JNI のアクセスがこの仮想マシンでサポートされていない場合は、NULL を返します。
jlong GetDirectBufferCapacity(JNIEnv* env, jobject buf);
指定された直接バッファー java.nio.Buffer によって参照されるメモリー領域のバイト数で示したサイズをフェッチし、返します。
JNIEnv
インタフェース関数テーブルのインデックス 231。
env: JNIEnv インタフェースポインタ
buf: 直接バッファー java.nio.Buffer オブジェクト (NULL は不可)
バッファーに関連付けられたメモリー領域のサイズをバイト数で返します。指定されたオブジェクトが直接バッファー java.nio.Buffer でない場合、または、直接バッファーへの JNI のアクセスがこの仮想マシンでサポートされていない場合は、-1 を返します。