第5章: 呼出しAPI
この呼び出しAPIにより、ソフトウェア・ベンダーはJava VMを任意のネイティブ・アプリケーションにロードできるようになります。 そのベンダーの提供するJavaが実行可能なアプリケーションは、Java VMソース・コードにリンクする必要がありません。
この章では、呼び出しAPIの概要の説明から始めます。 それ以降は、すべての呼び出しAPI関数のリファレンス・ページです。 次のトピックを取り扱います:
概要
次のコード例では、呼び出しAPIの関数の使用方法について説明します。 この例では、C++コードはJava VMを生成し、Main.test
と呼ばれるstaticメソッドを呼び出します。 明確にするために、エラー・チェックを省略しました。
#include <jni.h> /* where everything is defined */
...
JavaVM *jvm; /* denotes a Java VM */
JNIEnv *env; /* pointer to native method interface */
JavaVMInitArgs vm_args; /* JDK/JRE 19 VM initialization arguments */
JavaVMOption* options = new JavaVMOption[1];
options[0].optionString = "-Djava.class.path=/usr/lib/java";
vm_args.version = JNI_VERSION_19;
vm_args.nOptions = 1;
vm_args.options = options;
vm_args.ignoreUnrecognized = false;
/* load and initialize a Java VM, return a JNI interface
* pointer in env */
JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);
delete options;
/* invoke the Main.test method using the JNI */
jclass cls = env->FindClass("Main");
jmethodID mid = env->GetStaticMethodID(cls, "test", "(I)V");
env->CallStaticVoidMethod(cls, mid, 100);
/* We are done. */
jvm->DestroyJavaVM();
この例では、APIで2つの関数を使用しています。 呼び出しAPIは、ネイティブ・アプリケーションがJNIインタフェース・ポインタを使用してVM機能にアクセスできるようにします。
VMの生成
JNI_CreateJavaVM()
関数はJava VMをロードして初期化し、JNIインタフェース・ポインタへのポインタを返します。 JNI_CreateJavaVM()
をコールしたスレッドは「メイン・スレッド」とみなされ、Java VMにアタッチされます。
ノート:オペレーティング・システムに応じて、初期のプロセス・スレッドは、通常のJavaスレッド(スタック・サイズの制限やStackOverflowError
のスローなど)として正しく機能する機能に影響を与える特殊な処理に依存します。 Java VMのロードには初期スレッドを使用しないことを強くお勧めしますが、その目的のために新しいスレッドが作成されるだけです。
VMへの接続
JNIインタフェース・ポインタ(JNIEnv
)は、現在のスレッドでのみ有効です。 別のスレッドがJava VMにアクセスする必要がある場合、これは最初にAttachCurrentThread()
を呼び出して、自身をVMに接続しJNIインタフェース・ポインタを取得する必要があります。 VMにアタッチされると、ネイティブ・スレッドは、ネイティブ・メソッド内で実行される通常のJavaスレッドと同じように動作しますが、これは「コール依存のメソッド」の呼出し時にJavaの呼出し側が存在しないという例外です。 ネイティブ・スレッドは、DetachCurrentThread()
を呼び出して自身を切り離すまでVMに接続されたままになります。
接続されたスレッドには、相当量の作業を実行するのに十分なスタック領域が必要です。 スレッドごとのスタック領域の割当ては、オペレーティング・システム固有です。 たとえば、pthreadsを使用すると、スタック・サイズをpthread_create
のpthread_attr_t
引数に指定できます。
VMからの分離
VMにアタッチされたネイティブ・スレッドは、終了する前にDetachCurrentThread()
をコールして自身をデタッチする必要があります。 呼出しスタック上にJavaメソッドがある場合、スレッドは分離できません。
VMの終了
DestroyJavaVM()
関数は、Java VMを終了します。
この関数は、デーモン以外のスレッドが実行されないまで待機してから、実際にVMを終了します。 非デーモン・スレッドには、Javaスレッドおよびアタッチされたネイティブ・スレッドの両方が含まれます。 待機する理由は、デーモン以外のスレッドがロックやウィンドウなどのシステム・リソースを保持している可能性があるためです。 Javaアプリケーションまたはアタッチされたネイティブ・コードのプログラマは、スレッドが終了またはデタッチする前にこれらのリソースを解放する必要があります。 VMはこれらを自動的に解放できないため、プログラマはそれらを解放してから終了するまで待機します。
ライブラリおよびバージョン管理
ネイティブ・ライブラリは、動的にリンクされるか、またはVMと静的にリンクされます。 ライブラリとVMイメージを組み合せる方法は、実装に依存します。 System.loadLibrary
またはそれに相当するAPIは、ライブラリがロードされているとみなされると成功する必要があります。これは、動的リンク・ライブラリと静的リンク・ライブラリの両方に適用されます。
ネイティブ・ライブラリを一度ロードすると、すべてのクラス・ローダーからそのライブラリを認識できます。 そのため、異なるクラス・ローダーの2つのクラスが、同じネイティブ・メソッドにリンクしてしまう可能性がありました。 このため次の2つの問題が発生します。
- あるクラスは、異なるクラス・ローダー内で同じ名前を持つクラスがロードしたネイティブ・ライブラリと、誤ってリンクしてしまう可能性がある。
- ネイティブ・メソッドは、異なるクラス・ローダーからのクラスと容易に混同されてしまうことがある。 これにより、クラス・ローダーによって指定された名前空間の分類が破壊され、型の安全性の問題が引き起こされる。
各クラス・ローダーは、独自のネイティブ・ライブラリのセットを管理します。 同じJNIネイティブ・ライブラリを、2つ以上のクラス・ローダーにロードすることはできません。 そのようなことを行うと、UnsatisfiedLinkError
がスローされます。 たとえば、System.loadLibrary
を使用して2つのクラス・ローダーにネイティブ・ライブラリをロードしようとすると、UnsatisfiedLinkError
がスローされます。 この方法のメリットは次のとおりです。
- クラス・ローダーに基づく名前空間の分類は、ネイティブ・ライブラリに保管される。 ネイティブ・ライブラリは、異なるクラス・ローダーからのクラスを容易に混同することはない。
- 加えて、ネイティブ・ライブラリは、対応するクラス・ローダーのガベージ・コレクション時にアンロードできる。
静的リンク・ライブラリのサポート
'L'という名前のこれらの例で示されている静的にリンクされたライブラリの場合、静的にリンクされたライブラリには次の規則が適用されます:
- イメージがVMと結合されたライブラリ'L'は、ライブラリが
JNI_OnLoad_L
という関数をエクスポートする場合にのみ、静的リンクとして定義されます。 - 静的にリンクされているライブラリLによって
JNI_OnLoad_L
と呼ばれる関数とJNI_OnLoad
と呼ばれる関数がエクスポートされた場合は、JNI_OnLoad
関数が無視されます。 - ライブラリLが静的にリンクされている場合、
System.loadLibrary("L")
または同等のAPIの最初の呼出し時に、JNI_OnLoad
関数に指定されたものと同じ引数および期待戻り値で、JNI_OnLoad_L
関数が呼び出されます。 - 静的にリンクされているライブラリLでは、同じ名前のライブラリが動的にロードされることが禁止されます。
- このような関数がエクスポートされた場合は、静的にリンクされているネイティブ・ライブラリLを含むクラス・ローダーでガベージ・コレクションが実行されると、VMによってライブラリの
JNI_OnUnload_L
関数が呼び出されます。 - 静的にリンクされたライブラリLが
JNI_OnUnload_L
という関数とJNI_OnUnload
という関数をエクスポートする場合、JNI_OnUnload
関数は無視されます。
プログラマはJNI関数RegisterNatives()
を呼び出して、クラスと関連付けられたネイティブ・メソッドを登録することもできます。 RegisterNatives()
関数は、静的にリンクされた関数を使用する場合に特に有用です。
動的リンク・ライブラリがJNI_OnLoad_L
および/またはJNI_OnUnload_L
関数を定義する場合、これらの関数は無視されます。
ライブラリ・ライフサイクル関数フック
バージョン管理とリソース管理を容易にするために、JNIライブラリはloadとunload関数フックを定義することができます。 これらの関数の命名は、ライブラリが動的にリンクされているか静的にリンクされているかによって異なります。
JNI_OnLoad
jint JNI_OnLoad(JavaVM *vm, void *reserved);
動的にリンクされたライブラリによって定義されるオプションの関数。 (たとえばSystem.loadLibrary
を介して)ネイティブ・ライブラリがロードされると、VMはJNI_OnLoad
を呼び出します。
JNI APIの特定のバージョンで定義された関数を使用するには、JNI_OnLoad
は少なくともそのバージョンを定義する定数を返す必要があります。 たとえば、JDK 1.4で導入されたAttachCurrentThreadAsDaemon
関数を使用したいライブラリは、少なくともJNI_VERSION_1_4
を返す必要があります。 ネイティブ・ライブラリがJNI_OnLoad
関数をエクスポートしない場合、VMはライブラリがJNIバージョンJNI_VERSION_1_1
を要求しているだけであるとみなします。 VMがJNI_OnLoad
によって返されるバージョン番号を認識しない場合、VMはライブラリをアンロードし、ライブラリがロードされていないかのように動作します。
リンケージ:
ネイティブ・メソッドの実装を含む、動的にリンクされたネイティブ・ライブラリからエクスポートされます。
パラメータ:
vm
: 現在のVM構造体へのポインタ。
reserved
: 未使用ポインタ。
戻り値:
必要なJNI_VERSION
定数(GetVersion
も参照してください)を返します。
JNI_OnUnload
void JNI_OnUnload(JavaVM *vm, void *reserved);
動的にリンクされたライブラリによって定義されるオプションの関数。 ネイティブ・ライブラリを含むクラス・ローダーのガベージ・コレクションの際に、VMはJNI_OnUnload
を呼び出します。
この関数は、クリーンアップ・オペレーションに使用されます。 これは未確認のコンテキスト(ファイナライザからのコンテキストなど)で呼び出される関数なので、プログラマは慎重にJava VMサービスを使用する必要があります。またJavaコールバックを任意に行うことのないようにしなければなりません。
リンケージ:
ネイティブ・メソッドの実装を含む、動的にリンクされたネイティブ・ライブラリからエクスポートされます。
パラメータ:
vm
: 現在のVM構造体へのポインタ。
reserved
: 未使用ポインタ。
JNI_OnLoad_L
jint JNI_Onload_<L>(JavaVM *vm, void *reserved);
その必須機能は静的にリンクされたライブラリによって定義する必要があります。
'L'という名前のライブラリが静的にリンクされている場合、System.loadLibrary("L")
または同等のAPIの最初の呼び出し時に、JNI_OnLoad
関数で指定されたものと同じ引数および期待される戻り値でJNI_OnLoad_L
関数が呼び出されます。 JNI_OnLoad_L
は、ネイティブ・ライブラリが必要とするJNIバージョンを返さなければなりません。 このバージョンはJNI_VERSION_1_8
以降である必要があります。 VMがJNI_OnLoad_L
によって返されたバージョン番号を認識しない場合、VMはライブラリがロードされなかったかのように動作します。
リンケージ:
ネイティブ・メソッドの実装を含む静的にリンクされたネイティブ・ライブラリからエクスポートされます。
パラメータ:
vm
: 現在のVM構造体へのポインタ。
reserved
: 未使用ポインタ。
戻り値:
必要なJNI_VERSION
定数(GetVersion
も参照してください)を返します。 返される最小バージョンは少なくともJNI_VERSION_1_8
です。
導入されたバージョン:
JDK/JRE 1.8
JNI_OnUnload_L
void JNI_OnUnload_<L>(JavaVM *vm, void *reserved);
静的にリンクされたライブラリによって定義されるオプションの関数。 静的にリンクされたネイティブ・ライブラリ'L'を含むクラス・ローダーがガベージ・コレクトされると、そのような関数がエクスポートされると、VMはライブラリのJNI_OnUnload_L
関数を呼び出します。
この関数は、クリーンアップ・オペレーションに使用されます。 これは未確認のコンテキスト(ファイナライザからのコンテキストなど)で呼び出される関数なので、プログラマは慎重にJava VMサービスを使用する必要があります。またJavaコールバックを任意に行うことのないようにしなければなりません。
リンケージ:
ネイティブ・メソッドの実装を含む静的にリンクされたネイティブ・ライブラリからエクスポートされます。
パラメータ:
vm
: 現在のVM構造体へのポインタ。
reserved
: 未使用ポインタ。
導入されたバージョン:
JDK/JRE 1.8
情報ノート:
ネイティブ・ライブラリをロードする動作は、ライブラリとそのネイティブ・エントリ・ポイントをJava VMおよびランライムに認識させ、登録する完全なプロセスです。 単に、オペレーティング・システム・レベルの操作(UNIX(R)システムでのdlopen
など)を実行してネイティブ・ライブラリをロードするだけでは、この目標は完全には実現されないことに注意してください。 通常、ネイティブ関数は、ライブラリをメモリーにロードして、ネイティブ・ライブラリにハンドルを返すホスト・オペレーティング・システムの呼出しを実行するために、Javaクラス・ローダーから呼び出されます。 このハンドルは、以降のネイティブ・ライブラリのエントリ・ポイント検索の際に格納および使用されます。 ライブラリを登録するためにハンドルが正常に返されると、Javaネイティブ・クラス・ローダーでロード・プロセスが完了します。
呼び出しAPIの関数
JavaVM
型は、呼び出しAPI関数表へのポインタです。 次のコード例は、この関数表を示しています。
typedef const struct JNIInvokeInterface *JavaVM;
const struct JNIInvokeInterface ... = {
NULL,
NULL,
NULL,
DestroyJavaVM,
AttachCurrentThread,
DetachCurrentThread,
GetEnv,
AttachCurrentThreadAsDaemon
};
3つの起動API関数JNI_GetDefaultJavaVMInitArgs()
、JNI_GetCreatedJavaVMs()
およびJNI_CreateJavaVM()
は、JavaVM関数表の一部ではないことに注意してください。 これらの関数は既存のJavaVM
構造体がなくても使用できます。
JNI_GetDefaultJavaVMInitArgs
jint JNI_GetDefaultJavaVMInitArgs(void *vm_args);
Java VMのデフォルト構成を返します。 この関数を呼び出す前に、ネイティブ・コードはvm_args->versionフィールドを、VMでサポートされると予測されるJNIバージョンに設定する必要があります。 この関数から復帰すると、vm_args->versionは、VMがサポートする実際のJNIバージョンに設定されます。
リンケージ:
Java仮想マシンを実装するネイティブ・ライブラリからエクスポートされます。
パラメータ:
vm_args
: デフォルトの引数が格納されるJavaVMInitArgs
構造体へのポインタは、NULL
であってはなりません。
戻り値:
要求されたバージョンがサポートされている場合はJNI_OK
を返し、要求されたバージョンがサポートされていない場合はJNIエラー・コード(負の数)を返します。
JNI_GetCreatedJavaVMs
jint JNI_GetCreatedJavaVMs(JavaVM **vmBuf, jsize bufLen, jsize *nVMs);
作成されたJava VMをすべて返します。 VMへのポインタは、作成された順序でバッファvmBuf
に書き込まれます。 最大でbufLen
個のエントリが書き込まれます。 作成されたVMの合計数は、\*nVMs
で返されます。
1つのプロセスでの複数のVMの作成はサポートされていません。
リンケージ:
Java仮想マシンを実装するネイティブ・ライブラリからエクスポートされます。
パラメータ:
vmBuf
: VM構造が配置されるバッファへのポインタは、NULL
であってはなりません。
bufLen
: バッファの長さ。
nVMs
: 整数を指すポインタ。 NULL
値の可能性があります。
戻り値:
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
JNI_CreateJavaVM
jint JNI_CreateJavaVM(JavaVM **p_vm, void **p_env, void *vm_args);
ロードして、Java VMを初期化します。 現在のスレッドはJava VMにアタッチされ、メイン・スレッドになります。 p_env
引数をメイン・スレッドのJNIインタフェース・ポインタに設定します。
1つのプロセスでの複数のVMの作成はサポートされていません。
JNI_CreateJavaVM
への2番目の引数は常にJNIEnv *
へのポインタですが、3番目の引数は、オプション文字列を使用して任意のVM起動オプションをエンコードするJavaVMInitArgs
構造体へのポインタです:
typedef struct JavaVMInitArgs {
jint version;
jint nOptions;
JavaVMOption *options;
jboolean ignoreUnrecognized;
} JavaVMInitArgs;
options
フィールドは、次の型の配列です。
typedef struct JavaVMOption {
char *optionString; /* the option as a string in the default platform encoding */
void *extraInfo;
} JavaVMOption;
配列のサイズは、JavaVMInitArgs
のnOptionsフィールドに示されます。 ignoreUnrecognized
がJNI_TRUE
の場合、JNI_CreateJavaVM
では、"-X
"または"_
"で始まる認識されないすべてのオプション文字列が無視されます。 ignoreUnrecognized
がJNI_FALSE
の場合、JNI_CreateJavaVM
は認識できないオプション文字列を検出すると、ただちにJNI_ERR
を返します。 すべてのJava仮想マシンは、次の標準オプションのセットを認識する必要があります。
optionString | 意味 |
---|---|
-D<name>=<value> |
システム・プロパティを設定する |
-verbose[:class|gc|jni] |
冗長出力を有効にする。 各オプションの後に、VMが出力するメッセージの種類を示す、カンマで区切った名前のリストを続けることができる。 たとえば、「-verbose:gc,class 」は、VMにGCとクラス・ローディング関連のメッセージを出力するように指示する。 標準的な名前には、gc 、class 、およびjni 。 標準でない(VM固有の)名前はすべて、「X 」で始まる必要がある。 |
vfprintf |
extraInfo は、vfprintf フックへのポインタ。 |
exit |
extraInfo は、exit フックへのポインタ。 |
abort |
extraInfo は、abort フックへのポインタ。 |
モジュール関連のオプション--add-reads
、--add-exports
、--add-opens
、--add-modules
、--limit-modules
、--module-path
、--patch-module
、および--upgrade-module-path
は、"オプション値"フォーマットの代わりに"option=value"フォーマットを使用してオプション文字列として渡される必要があります。 ("option"と"value"の間で必要とされる=
に注意してください。) たとえば、java.management/sun.management
をALL-UNNAMED
にエクスポートするには、オプション文字列"--add-exports=java.management/sun.management=ALL-UNNAMED"
を渡します。
加えて、各VM実装は、標準でない独自のオプション文字列のセットをサポートします。 標準でないオプション名は、「-X
」またはアンダースコア(「_
」)で始まる必要があります。 たとえば、JDK/JREは-Xms
および-Xmx
オプションをサポートしているため、プログラマは初期および最大のヒープ・サイズを指定できます。 「-X
」で始まるオプションは、「java
」コマンド行からアクセス可能です。
次の例は、JDK/JREでJava仮想マシンを作成するコードです。
JavaVMInitArgs vm_args;
JavaVMOption options[4];
options[0].optionString = "-Djava.compiler=NONE"; /* disable JIT */
options[1].optionString = "-Djava.class.path=c:\myclasses"; /* user classes */
options[2].optionString = "-Djava.library.path=c:\mylibs"; /* set native library path */
options[3].optionString = "-verbose:jni"; /* print JNI-related messages */
vm_args.version = JNI_VERSION_1_2;
vm_args.options = options;
vm_args.nOptions = 4;
vm_args.ignoreUnrecognized = TRUE;
/* Note that in the JDK/JRE, there is no longer any need to call
* JNI_GetDefaultJavaVMInitArgs.
*/
res = JNI_CreateJavaVM(&vm, (void **)&env, &vm_args);
if (res < 0) ...
リンケージ:
Java仮想マシンを実装するネイティブ・ライブラリからエクスポートされます。
パラメータ:
p_vm
: 結果のVM構造体が配置される位置へのポインタ。 NULL
以外の値を指定してください。
p_env
: メイン・スレッドのJNIインタフェース・ポインタが配置される位置へのポインタ。 NULL
以外の値を指定してください。
vm_args
: Java VM初期化引数。 NULL
以外の値を指定してください。
戻り値:
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
DestroyJavaVM
jint DestroyJavaVM(JavaVM *vm);
Java VMの操作を終了し、VMリソースを解放するための最善の試みを行います。
どのスレッドでも、接続されているかどうかにかかわらず、この関数を呼び出すことができます。 現在のスレッドがアタッチされていない場合、最初にアタッチされます。 現在のスレッドがすでにアタッチされている場合は、コール・スタックにJavaメソッドがある場合はエラーになります。
この関数は、すべての非デーモン・スレッドが終了するまで待機し、現在のスレッドがデーモンでない場合は除外してから、停止シーケンス(java.lang.Runtimeを参照してください)を開始します。 シャットダウン・シーケンスが終了すると、Java VMは終了し、Javaコードを実行しているスレッドがそのコードの実行を停止し、それを実行できる関連するVMリソースを解放します。 この時点で、現在のスレッドはJava VMに接続されなくなり、この関数は呼び出し元に戻ります。
Java VMの終了時にネイティブ・コードを実行しているスレッドは、引き続きそのコードを実行しますが、Javaコードの実行を再開しようとすると、実行は停止します。 これには、デーモン・スレッドおよび停止シーケンスの開始後に開始された非デーモン・スレッドが含まれます。 daemonスレッドおよびnon-daemonスレッドという用語は、アタッチされたネイティブ・スレッドに関してのみ意味を持ちます。アタッチされていないネイティブ・スレッドは、Java VMの終了によって影響を受けません。
リンケージ:
JavaVMインタフェース関数表のインデックス3。
パラメータ:
vm
: 破棄されるJava VM。 NULL
以外の値を指定してください。
戻り値:
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
AttachCurrentThread
jint AttachCurrentThread(JavaVM *vm, void **p_env, void *thr_args);
現在のスレッドをnon-daemonスレッドとしてJava VMにアタッチします。 p_env
引数でJNIインタフェース・ポインタを返します。
すでにアタッチされているスレッドをアタッチしようとすると、p_env
引数に既存のJNIインタフェース・ポインタが返されます。 すでに接続されているスレッドのデーモンのステータスは、このメソッドを呼び出しても変更されません。
ネイティブ・スレッドを2つのJava VMへ同時に接続することはできません。
スレッドがVMに接続されている場合、コンテキスト・クラスのローダーは、ブートストラップ・ローダーです。
リンケージ:
JavaVMインタフェース関数表のインデックス4。
パラメータ:
vm
: 現在のスレッドがアタッチされるVMは、NULL
であってはなりません。
p_env
: 現在のスレッドのJNIインタフェース・ポインタが配置される位置へのポインタ。 NULL
以外の値を指定してください。
thr_args
: NULLまたはJavaVMAttachArgs
構造体を参照するポインタにして、追加情報を指定できます。
typedef struct JavaVMAttachArgs {
jint version;
char *name; /* the name of the thread as a modified UTF-8 string, or NULL */
jobject group; /* global ref of a ThreadGroup object, or NULL */
} JavaVMAttachArgs
戻り値:
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
AttachCurrentThreadAsDaemon
jint AttachCurrentThreadAsDaemon(JavaVM *vm, void **p_env, void *thr_args);
現在のスレッドをdaemonスレッドとしてJava VMにアタッチします。 p_env
引数でJNIインタフェース・ポインタを返します。
すでにアタッチされているスレッドをアタッチしようとすると、p_env
引数に既存のJNIインタフェース・ポインタが返されます。 すでに接続されているスレッドのデーモンのステータスは、このメソッドを呼び出しても変更されません。
ネイティブ・スレッドを2つのJava VMへ同時に接続することはできません。
スレッドがVMに接続されている場合、コンテキスト・クラスのローダーは、ブートストラップ・ローダーです。
リンケージ:
JavaVMインタフェース関数表のインデックス7。
パラメータ:
vm
: 現在のスレッドがアタッチされる仮想マシン・インスタンス。 NULL
以外の値を指定してください。
p_env
: 現在のスレッドのJNIEnv
インタフェース・ポインタが配置されるロケーションへのポインタ。 NULL
以外の値を指定してください。
thr_args
: NULLまたはJavaVMAttachArgs
構造体を参照するポインタにして、追加情報を指定できます。
typedef struct JavaVMAttachArgs {
jint version;
char *name; /* the name of the thread as a modified UTF-8 string, or NULL */
jobject group; /* global ref of a ThreadGroup object, or NULL */
} JavaVMAttachArgs
戻り値
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
DetachCurrentThread
jint DetachCurrentThread(JavaVM *vm);
Java VMから現在のスレッドを分離します。 呼出しスタック上にJavaメソッドがある場合、スレッドは分離できません。
このスレッドによって保持されているJavaモニターはすべて、(ただし、正しく記述されたプログラムでは、この時点までにすべてのモニターが解放されます)がリリースされます。 スレッドは終了したとみなされ、有効ではなくなりました。このスレッドの停止を待機しているすべてのJavaスレッドに通知されます。
VMからメイン・スレッドを切り離すことができます。
アタッチされていないスレッドを切り離そうとすると、何もしません。
DetachCurrentThread
が呼び出されたときに例外が保留されている場合、VMはその存在を報告することを選択できます。
リンケージ:
JavaVMインタフェース関数表のインデックス5。
パラメータ:
vm
: 現在のスレッドが分離されるVM。 NULL
以外の値を指定してください。
戻り値:
成功した場合はJNI_OK
を返し、失敗した場合は該当するJNIエラー・コード(負の数)を返します。
GetEnv
jint GetEnv(JavaVM *vm, void **p_env, jint version);
リンケージ:
JavaVMインタフェース関数表のインデックス6。
パラメータ:
vm
: インタフェースの取得元の仮想マシン・インスタンス。 NULL
以外の値を指定してください。
p_env
: 現在のスレッドのJNIインタフェース・ポインタが配置されるロケーションへのポインタ。 NULL
以外の値を指定してください。
version
: リクエストされたJNIバージョン。
戻り値:
現在のスレッドがVMに接続されていない場合は、*env
をNULL
に設定し、JNI_EDETACHED
を返します。 指定されたバージョンがサポートされていない場合は、*env
をNULL
に設定し、JNI_EVERSION
を返します。 それ以外の場合は、*env
を適切なインタフェースに設定し、JNI_OK
を返します。