ローカルメソッド呼び出し7

3320 ワード

いつの间にか7章になってしまいましたが、これ以上话すのは耻ずかしくて、こんなものを7章绍介しました...この章が終わったら実践しなければなりません.うん..
Javaプログラミング言語では,ローカルメソッドを使用することはプログラムにとって大きなセキュリティリスクを冒す.Cの運行期間、システムは配列の境界を越えた誤り、不良なポインタによる間接的な誤りに対していかなる防護を提供しない.したがって、ローカルメソッドのプログラマーにとって、Javaプラットフォームの完全性を維持するためにすべてのエラー条件を処理することは特に重要です.Javaプラットフォームの完全性を保証するために、すべてのエラー条件を処理することが特に重要です.特に、ローカルメソッドで解決できない問題を診断した場合は、Java仮想マシンに報告する必要があります.そして、この場合、自然と異常が投げ出されます.ただし、C言語に異常はなく、ThrowまたはThrowNew関数を呼び出して新しい例外オブジェクトを作成する必要があります.ローカルメソッドがリリースされるとjava仮想マシンはこの例外を放出します.
jclass class_EOFException = (*env)->FindClass(env, "java/io/EOFException");
jmethodID id_EOFException = (*env)->GetMethodID(env, class_EOFException, "<init>", ()V);
jthrowable obj_exc = (*env)->NewObject(env, class_EOFException, idEOFException);
(*env)->Throw(env, obj_exc);

通常、ThrowNewを使用すると便利です.クラスと「改良UTF-8」バイトシーケンスを提供するだけで、この関数は例外オブジェクトを構築します.
(*env)->ThrowNew(env, (*env)->FindClass(env, "java/io/EOFException"), "Unexpected end of file");

(C++における異常とJava異常は現在実現されていないので、C++異常が放出されないことを確認し、上記の方法でjava異常を放出する必要があります)
ThrowとThrowNewは例外のみ登録されているため,ローカルメソッドの制御フローを中断することはないので,一般的にはreturnに続く.
if(str == null){
    (*env)->ThrowNew(env, (*env)->FindClass(env, "java/lang/NullPointerException"), "str is NULL");
    return;
}

ローカルメソッドがjavaメソッドを呼び出す場合は、javaメソッドが例外を放出することを考慮する必要があります.
jthrowable obj_exc = (*env)->ExceptionOcurred(env);
jboolean occurred = (*env)->ExceptionCheck(env);

異常な保留がない場合、最初のメソッドはNULLを返します.第2の方法は、通常、異常タイプに関心を持たずに使用される.
for(i=0; cstr[i] != 0 && !(*env)->ExceptionCheck(env); i++)
(*env)->CallVoidMethod(env, out, id_print, cstr[i]);

OK、jniの基礎はやっと紹介しました.最後の一枚、ハイエンドのものをもう少しください.
もし、Javaコードを実行したいCまたはC++プログラムがあれば、API(Invocation API)を呼び出してJava仮想マシンをCまたはC++プログラムに潜入させることができます.以下は初期化に必要な基本コードです.
JavaVMOption options[1];
JavaVMInitArgs vm_args;
JavaVM *jvm;
JNIEnv *env;

options[0].optionString = "-Djava.class.path=.";

memset(&vm_args, 0, sizeof(vm_args));
vm_args.version = JNI_VERSION_1_2;
vm_args.nOptions = 1;
vm_args.options = options;

JNI_CreateJavaVM(&jvm, (void**)&env, &vm_args);

対JNI_CreateJavaVMの呼び出しにより仮想マシンが作成され、ポインタjvmが仮想マシンに、ポインタenvが実行環境に向けられます.
仮想マシンに任意の数のオプションを提供できます.これは、オプション配列のサイズとvm_を増やすだけです.args.nOptionssの値.
プログラムがトラブルに巻き込まれてプログラムがクラッシュし、JVMを初期化できないか、クラスをマウントできない場合は、JNIデバッグモードをオンにします.次のオプションを設定します.
options[i].optionString = "-verbose:jni";

JVMの初期化プロセスを説明する一連のメッセージが表示されます.あなたがロードしたクラスが見えない場合は、あなたのパスとクラスパスの設定を検察官してください.
仮想マシンを設定すると、前章で説明したようにJavaメソッドを呼び出すことができます.通常通りenvを使えばいいです.
jvmポインタは、API内の他の関数を呼び出す場合にのみ必要であり、現在は4つの関数しかありません.最も重要なのは、
(*jvm)->DestroyJavaVM(jvm);

仮想マシンの起動について、Androidのすべてのプログラムが仮想マシンの上に走っているとは思わなかったでしょう.彼が仮想マシンを起動する方法は、私たちが紹介した八九から十まで離れていないかもしれませんが、推測にすぎません.
Vistaによるリンクルールの変更により、JVMの作成に問題が発生し、クラスライブラリを手動でロードすることで解決できます.この問題は深く検討されていないが,jvmの作成とローカルシステムの関係も大きいことを示している.