4

私は、いくつかの COM インターフェイスを持つ API に取り組んでいます。問題は、API がその API をロードするプロジェクトによって実装されなければならないインターフェイスを介して通信することです。したがって、API を使用する場合は、API をプロジェクトにロードし、API によって呼び出されるメソッドを実装するクラスを作成して、特定のことを通知したり、結果を渡したりします。

これは明らかにマーシャリングの悪夢になります。さらに、さまざまなプラグインやマネージャーから、API 通知機能に登録されている通知用に呼び出されるメソッドを実装するすべてのオブジェクトに API を介して呼び出しを渡す中間オブジェクトもいくつかあるため、これは手に負えなくなりつつあります。複雑さの。

APIをロードする人が行う必要がある作業を短縮するために、APIがフリースレッドモデルに従う場合、ダイアログなどのMFCによって生成されたクラスが必要なCOMインターフェイスを実装することは可能ですか?通知用?API がこれらのメソッドを呼び出せるように、そのようなオブジェクトを IStream に変換し、API 側でインターフェイスに戻す必要があることに注意してください。

私の知る限り、MFC ダイアログはデフォルトで STA です。それらを強制的に変更したり、MTA で開始したりする方法はありますか? COMの観点からも合法ですか?物事が複雑になるため、別のスレッドで通知を処理するために別のオブジェクトを作成しないようにしています。この API は複数の場所で使用する必要があり、GUI やサービスなどで使用する必要があります。

4

1 に答える 1

2

API自体はスレッドの制御に限定されておらず、COMシンクインターフェイスを介してバックグラウンドスレッドで通知を取得することを意図していることを理解しています。

COM との親和性を維持しながら問題に対処するには、3 つの方法があります。最も簡単な方法は、アプリケーションのグローバル アパートメント モデルを変更して、「メイン」GUI スレッドが MTA として初期化されるようにすることです。これは機能する可能性がありますが、「Arartment」スレッド モデルに登録された ActiveX コントロールなど、他のものと互換性がないことがすぐにわかる場合があります。

もう 1 つのオプションは、COM スレッド ガイドラインにわずかに違反することです。これにより、API はシンク インターフェイスをマーシャリングせずにバックグラウンド スレッドから直接使用します。これは、サイド スレッドで呼び出しを受信するように準備された MFC アプリケーションで正常に機能し、実際には非常に簡単に実行できます (API 側のスレッド/アパートメント間で自発的にシンク インターフェイス ポインターを渡すだけです)。クロス アパートメント インターフェイス ポインターの使用を検出する .NET クライアントによって API が使用されると、後で問題が発生する可能性があります。

COM フレンドリにし、UI スレッドで STA スレッドを使用するには、次のシナリオを実装できます。API は、直接渡されたシンク インターフェイスを受け入れる STA コンポーネントにすることができます (STA の MFC クラスによって実装された COM オブジェクト、またはウィンドウ クラスなどに直接実装された COM インターフェイスなどのより単純なもの)。API は、ワーカー スレッド (CoMarshalInterThreadInterfaceInStreamと友達)。API は非整列化ポインターを使用して、MTA スレッドから通知を配信します。これには通常、不要な元のスレッドへのスレッドの切り替えが含まれるため、これを回避するには、MFC 側の通知クラスでフリー スレッド マーシャラーを実装する必要があります。これにより、マーシャリングされていないインターフェイス ポインターがワーカー スレッドで直接呼び出しを受け取り、MFC アプリケーションがスレッドの同期 (クリティカル セクションなど) を担当するように変更されます。これは、STA、COM フレンドリー、API ワーカー スレッドであり、同時に効率的です。

于 2013-09-19T08:56:14.177 に答える