8

次のような Windows MFC アプリケーションがあります。

(1) JVM をロードします ( JNI_CreateJavaVM())

(2) メインスレッドを JVM に接続します ( AttachCurrentThread())

(3) いくつかの Java クラスとメソッド (FindClass()およびGetMethodID()/ GetStaticMethodID())をロードします。

(4) Java コードで使用するためのいくつかのネイティブ コールバックを登録します ( RegisterNatives())

(5) JVM からスレッドをデタッチします ( DetachCurrentThread())

(6) JVM を破棄します ( DestroyJavaVM())

上記の関数はすべて、アプリケーションを実行するたびに成功します。上記に加えて、アプリケーションとやり取りして Java 静的メソッドを正常に呼び出し、これらの Java メソッドがネイティブ コールバックを正常に呼び出すため、それらが成功することはわかっています。私のアプリケーションは正常に終了し、予期された Java 関数とネイティブ コールバックが実行されたことは確かです。

ただし、アプリケーションを実行するたびに、への呼び出しはJNI_CreateJavaVM()失敗します ( JavaVM *. アプリケーションの実行間でまったく何も変わりません。単純に 1 回実行し (上記の 6 つの手順以外は何もしなくても、正常に実行されます)、正常に終了し、再度実行すると失敗します。前後の成功/失敗に例外はありません。何十回も実行でき、成功と失敗の間で1回おきに正確に振動しJNI_CreateJavaVM()ます。

必要に応じて、さらにコードを貼り付けます。ただし、誰かが私が提供したものについて洞察を持っていることを願っています。(注: これは BCGSoft MFC のプロパティ シート アプリケーションですが、私はそれが重要であるかどうかを強く疑っています。)

4

1 に答える 1

4

おそらく修正されることのないこのバグ(ここで再掲) に遭遇しているようです。

その名前にもかかわらず、DestroyJavaVM()実際には JVM を破棄しません。シャットダウンする必要があることを JVM に通知しますが、JVM は実際にシャットダウンする前に、メイン スレッド以外のすべてのスレッドが停止するまで待機します。実際、ドキュメントには次のように記載されているように(非常に暗号化されています)、「ただし、JDK/JRE はまだ VM のアンロードをサポートしていません。」

また、ステップ 2 の「メイン スレッドを JVM にアタッチする」も気になります。JVM を作成したスレッドを JVM にアタッチする必要はなく、そのスレッドをデタッチすることもできません。あなたが本当にそれをしているなら、それがあなたのシステムを台無しにしている可能性があります. (JVM を作成するスレッドは、JVM の「メイン」スレッドです。他のネイティブ スレッドが JVM にアクセスする必要がある場合にのみ、他のネイティブ スレッドを JVM にアタッチ/デタッチする必要があります。)

ところで、JNI_CreateJavaVM()成功すると 0 を返し、「失敗」したときは 0 を返すとのことですが、どのような意味で失敗しているのでしょうか。どの JVM (バージョン、ベンダー) を使用していますか?

于 2012-05-17T06:38:10.403 に答える