3

私はネイティブとして C++ を使用して JNI で作業しています。(c++) 共有ライブラリを作成でき、共有ライブラリの助けを借りて Java 関数を呼び出すことができます。

私のプロセスに含まれる手順:

1) JNI_CreateJavaVm.[IN C++] を使用して VM を作成する

2) 作成した VM で処理します。

3) スレッドを終了する

同じプロセスをもう一度実行すると、JNI_CreateJavaVm は VM を作成せず、JNI エラー コードを -1 (不明なエラー) として返します。 GetEnv がクラッシュしました。

関数 GetJavaVM も試しましたが、エラー メッセージが表示されてクラッシュしています。

#
# A fatal error has been detected by the Java Runtime Environment:
#
#  SIGSEGV (0xb) at pc=0x00c1b3ed, pid=8645, tid=2961177456
#
# JRE version: 7.0_25-b15
# Java VM: Java HotSpot(TM) Server VM (23.25-b01 mixed mode linux-x86 )
# Problematic frame:
# C  [libVsphere.so+0x6a3ed]  _Jv_JNIEnv::GetJavaVM(_Jv_JavaVM**)+0xb

なぜそれが起こっているのか、そして問題を解決する方法は?

マルチスレッド環境で JNI_CreateJavaVm、JNI_GetCreatedVMs、および GetJavaVM を使用する方法。

4

2 に答える 2

4

プログラムの開始時に 1 つのスレッドのみで作成された JavaVM のグローバル インスタンスを 1 つだけ持つ必要があります。

/* Global instance */
JavaVM *jvm;

int main() {
/* ...call to JNI_CreateJavaVm ...*/
}

次に、各スレッドで Java 環境を取得する場合は、Java マシン ( jvm )へのグローバル ポインターを使用して実行する必要があります。

JNIEnv *env;
(*jvm)->AttachCurrentThread(jvm, (void **)&env, NULL);

最終的にその環境を使用して、メソッド/クラスなどにアクセスできます:

jclass ex = (*env)->FindClass(env, "java/lang/NullPointerException");
于 2013-08-27T17:10:59.203 に答える
3

を使用AttachCurrentThread()して、現在のスレッドを既存の Java VM に接続できます。スレッドごとに JavaVM を作成する必要はありません。

于 2013-08-27T17:06:50.313 に答える