1

一部の DLL を暗黙的にロードし、他の DLL を明示的にロードする EXE を用意します (LoadLibrary)。この EXE は、その ExitProcess を実行しており (残りのプロセスで 1 つのスレッド)、そのビジー状態の一部として、A.DLL などの DLL をアンロードしています。

A.DLL には (残念ながら) static があります。atexit コールバックが呼び出され、この static のデストラクタが呼び出され始め、デストラクタが何らかのクリーンアップを実行することを決定し、これを実行するために DLL をロードするまで、デストラクタの跡が残ります。この DLL は、この DLL で使用しようとしていたスタティックが存在しないため、メモリ アクセス違反が原因でクラッシュが発生するまで、いくつかのメソッドを実行します。このスタティックのスタック トレースを見ると、デストラクタは DLL アンロードの一部として既に呼び出されています。

どうしたの?DLL がロードされ、いくつかのメソッドが実行され、(同じ DLL 内で) 静的を使用するようになりましたが、これは破棄されました (静的は、dll がアンロードされたときにのみ破棄されます)。では、メソッドを実行している半端な状態にあるだけでなく、破壊されているのでしょうか?

EXE は __tmainCRTStartup のコンテキストにあるようです。これは、ユーザーが作成したメインが返されたことを意味しますか? ユーザー main または tmainCRTStartup のコンテキストで DLL がアンロードされていますか?

4

1 に答える 1

4

これは単純です。静的オブジェクトのデストラクタは、作成の逆の順序で呼び出されます。これは、atexit コールバックを登録することによって内部的に行われます。これが異なる唯一のケースは、DLL を手動でアンロード (FreeLibrary) した場合です。

あなたが説明した問題は、静的コンストラクター/デストラクタで簡単に発生する循環依存関係があることを示しているだけです。特に、この時点で DLL をロードすることは非常に危険に思えます。

于 2012-10-17T12:11:33.947 に答える