私はこれを投稿するのを助けることはできませんが、それは質問に対する直接的な答えではありません。
Comの黄金時代からの素晴らしいMSKBの記事があります: 情報:OLEスレッドモデルの説明と仕組み. 。まだそこに、そしてすべての関連情報があります。 ポイントは、ルールに従っている場合、マーシャリングがあるかどうかを心配しないでください。. 。オブジェクトを次のように登録するだけです ThreadingModel=Both
, 、フリースレッドマーシャラーを集計します CoCreateFreeThreadedMarshaler
, 、そして完了します。 comは、必要に応じて可能な限り最善の方法でマーシャリングを行います。クライアントのアパートモデルに応じて、クライアントコードは、ルールにも従う場合、インターフェイスへの直接的なポインターを受信する場合があります。
インターフェイスのメソッドが呼び出されたときに受信できる「エイリアン」インターフェイスは、同じスレッドにとどまるため、コールの範囲で有効になります。 保存する必要がない場合は、それだけです。
ただし、「エイリアン」インターフェイスをキャッシュする必要がある場合、これを行う正しい方法は、それを使用して保存することです CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
:
保存するには:
- クリティカルセクションを入力します。
- 電話
CoMarshalInterThreadInterfaceInStream
と保存します IStream
メンバーフィールドのポインター。
- 重要なセクションを離れます。
それを取得するために
- クリティカルセクションを入力します。
- 電話
CoGetInterfaceAndReleaseStream
インターフェイスを取得します
- 電話
CoMarshalInterThreadInterfaceInStream
そしてそれをもう一度保存します IStream
将来の使用のために
- 重要なセクションを離れます。
- 現在の呼び出しの範囲でインターフェイスを使用します
それをリリースするには:
- あなたがそれを保持する必要がなくなったら、保存されたものをリリースするだけです
IStream
(重要なセクション内)。
「エイリアン」オブジェクトも自由に傾いており、同じプロセス内で物事が起こっている場合、後に直接インターフェイスポインターを扱う可能性があります CoGetInterfaceAndReleaseStream
. 。ただし、仮定を立てるべきではありません。また、取引しているオブジェクトが元のオブジェクトであるか、com marshallerプロキシであるかを知る必要はありません。
これは、使用することでわずかに最適化できます CoMarshalInterface
w/ MSHLFLAGS_TABLESTRONG
/ CoUnmarshalInterface
/ IStream::Seek(0, 0)
/ CoReleaseMarshalData
それ以外の CoGetInterfaceAndReleaseStream
/CoGetInterfaceAndReleaseStream
, 、ストリームをリリースせずに、必要に応じて何度も同じインターフェイスを除外します。
スレッドローカルストレージを含む、より複雑な(おそらくより効率的な)キャッシュシナリオが可能です。しかし、私はそれが過剰になると信じています。私はタイミングをしませんでしたが、私はのオーバーヘッドだと思います CoMarshalInterThreadInterfaceInStream
/CoGetInterfaceAndReleaseStream
本当に低いです。
そうは言っても、あなたが状態を維持する必要があるなら スレッドアフィニティを必要とする可能性のあるリソースまたはオブジェクトを保存します, 、前述のcomインターフェイス以外に、あなた いけない あなたのオブジェクトをとしてマークします ThreadingModel=Both
またはFTMを集計します。