COMオブジェクトを基本的にC++クラスであると説明している2つの記事を読みました。これは本当ですか?これが私が読んでいる記事の1つです:http://www.codeproject.com/Articles/13601/COM-in-plain-C
CでCOMオブジェクトを作成する方法について説明します。COMは、この構造体の最初のメンバーが特定の関数ポインターであることを強制します。
COMオブジェクトとC++の具体的な相関関係はわかりませんが、関係は簡単に理解できます。
COMオブジェクトを基本的にC++クラスであると説明している2つの記事を読みました。これは本当ですか?これが私が読んでいる記事の1つです:http://www.codeproject.com/Articles/13601/COM-in-plain-C
CでCOMオブジェクトを作成する方法について説明します。COMは、この構造体の最初のメンバーが特定の関数ポインターであることを強制します。
COMオブジェクトとC++の具体的な相関関係はわかりませんが、関係は簡単に理解できます。
COM は、仮想関数テーブル ポインター (別名 vtable ポインター) をオブジェクトの最初のメンバーとして、そのオブジェクトをどのように配置するかを正確に指定します。Microsoft コンパイラが C++ オブジェクトをレイアウトする方法とレイアウトが同じになるように設計されているため、手動で定義された C 構造と同じようにコンパイルされる C++ クラスを使用できます。
Microsoft コンパイラを使用している限り、COM オブジェクトは基本的に C++ クラス インスタンスです。ただし、別のコンパイラを使用している場合は、C++ オブジェクトが同じ方法でレイアウトされるように特別な注意を払う必要があります。多重継承または仮想継承を使用していない限り、ほとんどのコンパイラは vtable を最初に配置するため、通常は機能しますが、一部のコンパイラは vtable を最後に配置します。コンパイラのドキュメントを読んで、それが COM 互換かどうかを確認してください。
IMO、これは COM オブジェクトの定義方法に少し依存します。COM オブジェクトが COM Binary Interface と互換性のあるオブジェクトである場合、オブジェクトが C++ で内部的に実装されているかどうかは実装の詳細です。これは C++ で実装できますが、他のあらゆる方法で実装することもできます。また、COM インターフェイスを介してアクセスする限り、ほとんど意味がありません。
そうは言っても、Adam と WhozCraig が指摘したように、COM の Binary Interface は MSVC の C++ コンパイラを念頭に置いて設計されています。MSVC C++ で COM オブジェクトを記述することは、COM オブジェクトを作成する「元の」方法でした。したがって、この 2 つは間違いなく絡み合った歴史を持ち、実際、COM Binary Interface 仕様は、MSVC が C++ オブジェクトをレイアウトする方法と多くの共通点があります。ただし、MSVC コンパイラは、「追加の」コンパイル手順として COM バインディングを生成する必要があります (たとえば、COM タイプ ライブラリ、および C++ インポート ヘッダーを使用して、他の C++ プロジェクトが COM ライブラリをインポートできるようにする)。
COM オブジェクト仕様は、C++ オブジェクトの既存のバイナリ レイアウトを利用するように設計されているため、その意味では C++ クラスに基づいています。
IDispatch インターフェイスは、C++ vtables を使用できない言語から簡単に COM を使用できるようにするために作成されました。COM 呼び出しに間接的なレイヤーを追加します。
別の回答を追加します。COM と C++ の両方について知っておくと、他の回答ではカバーされていない非常に役立つことがいくつかあると思います。
おそらく、次の 3 つの重要な情報を取得する必要があります。
COM オブジェクトは、実際には COM インターフェイス の集合であり、これらは協力して、共有の COM オブジェクト ID を持っているように見えます (任意のインターフェイスから他のインターフェイスに QI を実行できます。これらのインターフェイスの 1 つは、QI を実行するたびに返されるインターフェイスです)。 IUnknown の場合、別名「正規の未知数」)。
COMインターフェイスは、MSVCおよびすべての(AFAIK)Windowsコンパイラによって実装されているC++オブジェクトのvtableと同じレイアウトをたまたま持っています。
COM はインターフェイスに重点を置いています。C++ はクラスに重点を置いています。
2 つ目は、C++ での COM オブジェクトの実装を簡単にするものです。しかし、これらの最初のものは、テーマに多くのバリエーションがあることを意味します. したがって、次のことができます。
1 つのインターフェイスを実装するクラスとして C++ で実装される単一インターフェイスの COM オブジェクト
C++ の多重継承を使用して、複数のインターフェイスを実装する C++ クラスとして実装される、複数のインターフェイスを持つ単一の COM オブジェクト。
連携する C++ オブジェクト インスタンスのコレクションを実装する複数のインターフェイスを持つ単一の COM オブジェクト。おそらく COM インターフェイスごとに 1 つの C++ クラス。または、COM オブジェクトのほとんどのインターフェイスを実装する 1 つの C++ クラスと、ヘルパー C++ クラスを使用して使用頻度の低いインターフェイスを実装し、おそらく必要に応じてその場でのみこれらのヘルパー C++ クラスを作成します! (これも COM 集約とは別のものであることに注意してください。)
この最後のケースは、単一の COM オブジェクトが実装時に複数の C++ オブジェクトにマップできることを示しているため、特に興味深いものです。COM のルールに従う限り、COM は気にしません (特に refcounting に関しては、QI は連想、再帰、および推移的である必要があり、すべての COM オブジェクトには Canonical IUnknown が必要です)。
C++ で COM オブジェクトを実装するのはかなり簡単ですが、手に入れた COM オブジェクトが実際に舞台裏で C++ クラスであると想定することはできません。C、アセンブラーで実装されているか、動的に生成されている可能性があります。一部の C# コードのラッパーであるコード片。
RTTI や C++ 例外などの C++ 機能は COM の一部ではないため、任意の COM オブジェクトに対してそれらを使用することはできないことに注意してください。もちろん、それが実際に独自の C++ クラスの 1 つであることを知っている場合を除きます。オブジェクトを COM オブジェクトとしてではなく、C++ クラスとして実際に使用します。
COM はコンポーネント オブジェクト モデルの略です。Globally Unique Identifier (GUID) であるクラス ID (CLSID) によって識別されるさまざまな種類のコンポーネントを使用して構築されたライブラリです。各 COM コンポーネントは、1 つまたは複数のインターフェイスを介してその機能を公開します。コンポーネントによってサポートされるさまざまなインターフェイスは、GUID でもあるインターフェイス ID (IID) を使用して互いに区別されます。