MT問題のような視線を見ていますが、COM +で使用されるSTAモデルを詳しく理解しようとしています。レガシーVB6 COM + DLLがネイティブWin32 DLLを呼び出す - STAのスレッディング問題?
効果的には、VB6で書かれた従来のCOM +コンポーネントがあり、C++で書かれたネイティブ(つまり、COMではない)Win32 DLLを呼び出します。
問題が発生したときにログメッセージがファイル内にインターリーブされていることを確認するために、いくつかの間欠的な問題(テストでは再現できない問題)が発生しました。 DLLが一度に2つのスレッドによって呼び出されていることを暗示しています。
ここで、_getpid()とGetCurrentThreadId()に基づいてスレッドごとのファイルにロギングが行われるため、C++ DLLのコードが呼び出されると同時に同じスレッドで2回呼び出されるようです。私のSTAの理解によれば、COMが1つのスレッド上のオブジェクトの個々のインスタンスを一時停止して実行を再開すると、これが当てはまる可能性があります。
ここではどこから行くのか不安です。私は、これがSTA DLLであることをCOMに伝えるためにDllMain()でCoInitialiseEx()を呼び出す必要があることを読んでいますが、これはCOM DLLに対してのみ有効で、ネイティブDLLには影響しません。他の唯一のオプションは、DLLの一部をクリティカルセクションとしてラップしてアクセスをシリアライズすることです。
私はDLLを再作成しようとすることができましたが、共有状態もグローバル変数もありません - すべてがローカル変数にあります。したがって、各呼び出しは独自のスタックを取得する必要がありますが、STAモデルは基本的にこれに奇妙な影響を与え、別の呼び出しと同じエントリポイントで既にロードされているDLLに再入力するだけです。残念なことに、私はこの理論をどのように証明するかテストする方法を知らない。
質問は基本的には、次のとおりです。
- STA COM +コンポーネントは、ネイティブDLLを呼び出すと、STAモデルでは何が にありませんが中断され、制御は別の「スレッドに渡されているアクティブな「スレッド」を防ぎます"DLL呼び出しの途中で?
- CoInitialiseEx()はこれを解決する正しい方法ですか?
- (1)または(2)のどちらも「良い」仮定でない場合、何が起こっていますか?
>>同じスレッドで同時に2回呼び出されています。 <<今は面白いことですが、「同時に」することはできません。おそらく、このコードは再帰的に自分自身を最高の状態で呼び出すでしょう。 – wqw