どのようにC ++で複数のCOMインターフェイスの作業を実施していますか?
-
27-09-2019 - |
質問
私は、ブラウザヘルパーオブジェクトに関するのこの例のコードを理解しようとしています。
の内部には、作者が実装複数のインタフェース(IObjectWithSite、のIDispatch)を露出させる単一のクラス
彼のQueryInterface関数を行い、次のます:
if(riid == IID_IUnknown) *ppv = static_cast<BHO*>(this);
else if(riid == IID_IObjectWithSite) *ppv = static_cast<IObjectWithSite*>(this);
else if (riid == IID_IDispatch) *ppv = static_cast<IDispatch*>(this);
私はCの観点から、インターフェイスポインタがvtableをするだけのポインタであることを学びました。私はそれがC ++はstatic_castをを使用してインターフェイス実装いずれかの仮想テーブルを返すことが可能であることを意味するために取るます。
これは、このように構成されたクラスは、メモリ内のvtableの束(IObjectWithSite、IDispatchを、など)を持っていることを意味するのでしょうか?何がC ++異なるインターフェイス上の名前の衝突(彼らそれぞれのQueryInterface、のAddRefとRelease機能を持っている)、私はこれらのそれぞれに異なる方法を実装することができ、?
で行います解決
はい、複数のVテーブル、各継承インタフェースのための1つが存在します。 static_cast <>はそれを返します。コンパイラは、同じ関数へのポインタと各Vテーブルのスロットを埋め、継承されたインターフェイスで一般的な方法は、共有されていることを確認します。だから、あなただけのAddRef、リリース、QueryInterfaceをの一実装を必要としています。ちょうどあなたが何をしたいです。これのどれも偶然ではない。
同じ方法で、これが唯一のこれまで問題となっているときコクラス実装し、複数のインタフェースますはは同じ実装を与えたくないということ。でIConnectionPoint ::アドバイス()メソッドは、悪名高い例です。それとも、)(DAdviseでしたか?残念ながら、私はそれはと衝突し、それが解決されたか、それはATLの内部で覆われていたものを覚えていません。非常に良い本ところでます。
他のヒント
this
ポインタを与えられた場合、多重継承のは、複数のvtableは、次の形式のような順序で配置されている(最初のバイトにその時点、01)
[01] [02] [03] [04] [05] [06] [07] [08] [09] [10] [11] [12]
【VTableAのPTR] [VTableBのPTR] [VTableCのPTR]
はC ++は、複数のインタフェースシナリオで関数プロトタイプごとに生成されます。 しかし、通常の継承のシナリオのために、スーパークラスが事前に定義されている場合があります機能をオーバーライドする実装と子供たちは、親とは別のコンテンツを指す自分のvtableを持つことになります。