3

COMオブジェクトを使用したいクライアントがその方法を知ることができるように、COMがそのオブジェクトのレイアウトをどのように指定するかを理解しようとしています。

複数のインターフェイスを実装する COM オブジェクトは、ネストされたクラスや多重継承を使用するなど、さまざまな方法でそれを実行できることを読みました。

私の理解では、両方の手法が同じメモリ レイアウト (COM 仕様に準拠) を生成する必要があるため、COM オブジェクト (たとえば C) を使用するクライアントは、その方法を知ることができます。

したがって、私の具体的な質問は、多重継承とネストされたクラスを使用して実装された c++ オブジェクトのメモリ レイアウトに違いがあるかどうかです。

また、COM オブジェクトのレイアウトが指定されている場所を教えてもらえますか?

4

4 に答える 4

8

COM は、オブジェクトのメモリ レイアウトに完全に依存しません。必要なものは、 を呼び出すときの関数ポインタのテーブルだけですIUnknown::QueryInterface()。どのように実装するかは完全にあなた次第です。MFC は入れ子になったクラスを使用しますが、それ以外のほとんどの場合、C++ コンパイラの多重継承の組み込みサポートを利用します。MSVC++ コンパイラがそれを実装する方法は、COM が必要とするものと完全に互換性があります。これは偶然ではありません。IUnknown を適切に実装する方法を示している COM に関する書籍に記載されているボイラープレート コードを使用してください。

于 2011-01-05T21:20:39.597 に答える
5

COM で指定されている唯一の「レイアウト」は、各インターフェイスに関連付けられた vtable (仮想関数ポインター テーブル) です。すべてのインターフェイスは IUnknown から派生するため、クライアントがポインタを持つオブジェクトのインターフェイスが何であれ、QueryInterface を呼び出して、同じオブジェクトの別のインターフェイスを取得できます。

オブジェクトに必須のレイアウトはありません。実際、COM におけるオブジェクトの全体的な考え方は、OO 言語におけるクラス インスタンスとは大きく異なります。2 つのインターフェイスが同じ COM オブジェクトによって公開されているかどうかを知る唯一の方法は、両方の IUnknown インターフェイスに対して QueryInterface を呼び出すことです。それらが同じインターフェイス ポインターを返す場合にのみ、それらは同じオブジェクトへのインターフェイスです。

これは非常に柔軟なアイデアです。

  • たとえば、内部状態の一部のみがメモリにロードされた COM オブジェクトを持つことができます。さらにインターフェイスが要求されると、状態の他の部分が遅延ロード/割り当てられる可能性があります。
  • COM オブジェクトの状態は、連続していない複数のメモリ領域に分散している場合があります。
于 2011-01-05T21:31:14.460 に答える
1

単一のCOMインターフェースが多重継承を持つことができるとは思いませんが、クラスは多重継承を通じて複数のインターフェースを実装する場合があります。したがって、多重継承レイアウトは関係ありません。各インターフェイスには一意のレイアウトがあり、適切なレイアウトへのポインタを提供するのはコンパイラの責任です。

単一継承の場合、コンパイラーは親クラス定義を先頭に配置し、その後に子クラスを配置します。これはデータ要素の標準で定義されていますが、インターフェイスにはデータがないため、これも関係ありません。この標準では、vtableの存在やレイアウトについては何も述べられていませんが、ポリモーフィズムが機能するには、同じ方法でレイアウトする必要があります。つまり、最初に親、次に子です。

多重継承を通じて複数のインターフェースを実装すると、驚くべき事実がわかります。あるインターフェイスから別のインターフェイスにクラスオブジェクトへのポインタをキャストすると、アドレスが変更されます。これは、異なるインターフェイス(vtables)がインターフェイス宣言と一致する必要があるため、異なるレイアウトが必要であるためです。これらのレイアウトはすべて同じオブジェクト内に含まれていますが、コンパイラーはキャスト時にポインター操作を実行して、適切なサブセットに取得します。

于 2011-01-05T20:57:33.980 に答える
0

混合に関与する仮想関数がある場合、特に最も派生したクラスが独自のいずれかを追加する場合、両方のアプローチのメモリ レイアウトは異なります。

于 2011-01-05T20:48:08.243 に答える