2

次の静的/グローバルを持つDLLがあるとします。

ClassA Object;

ClassAの実装に加えて、「通常の」ClassBも含まれています。これは、ClassAがまだ構築されていない場合は正しく機能しません(これが、ClassAを静的/グローバルにした理由です)。

Windowsでは、DLLローダーがClassBのコンストラクターの呼び出しでこのDLLをロードすると思いますよね?この時点で、ClassAが構築され、次にClassBの構築が続きます。2番目のスレッドがやって来てClassBを構築する場合、ClassAはすでに構築されているため、構築されません。

さて、私の質問は、ClassBが2つのスレッドによって同時に構築された場合はどうなるかということです。したがって、スレッド1はClassAの構築を開始します。スレッド2は、ClassBのコンストラクターを実行する前に、ClassAが完全に構築されるまで待機しますか?

言い換えると、LoadLibrary()はCriticalSectionを使用して、DLLの静的/グローバルのスレッドセーフな初期化を保証しますか?私の勘は「はい」ですが、いずれかの方法で述べているドキュメントが見つからないようです。

4

3 に答える 3

1

DllMain「ローダーロック」と呼ばれる内部クリティカルセクションを保持しているときにWindowsローダーによって呼び出されるため、静的コンストラクターはDLL_PROCESS_ATTACHイベント中に呼び出されます。これは、DLLが最初にロードされたときに1回だけ発生します。

于 2009-12-26T05:51:10.517 に答える
1

DllMain のドキュメントを参照してください。ローダーのロックと初期化の順序について話していると思います。

于 2009-12-10T00:39:31.383 に答える
0

DLL は複数のプロセスで共有されるため、EXE のように初期化されません。必要なのは、事実上、他のオブジェクトのワンタイム ファクトリであるシングルトン オブジェクトです。

ここで、「ClassA」と「ClassB」は、これらのクラスのインスタンスを意味すると仮定していることに注意してください...

たとえば、次のようなものを持つことができます

ClassA& GetTheClassAInstance();
ClassB& GetTheClassBInstsance();

これらが初めて呼び出されたとき、これらの関数は、ClassA と ClassB のグローバル インスタンスが適切に構築されていることを確認します。

于 2009-12-10T03:05:56.103 に答える