web-dev-qa-db-ja.com

従来のDLLとCOM DLL

現在COMを勉強しています。 COM DLLは、従来のDLLインフラストラクチャに基づいて構築されています。COMDLLをビルドする場合、従来のDLLメソッドをエクスポートして、内部COMコクラスにアクセスします。

COMがバイナリレベルでコンポーネントを再利用するためのものである場合、従来のDLLは同じことを達成できると思います。どちらも機能を公開しているため、どちらもバイナリであるので、COMアプローチに移行するポイントは何ですか? ?

現在、私は伝統的なDLLメソッドを "flat"で公開しているのに対し、COM DLLメソッドを公開している"[〜#〜] oop [〜#〜]"階層方式です。OOP方式はより良いアプローチのようです。これが理由かもしれませんなぜCOMが優勢なのですか?

どうもありがとう。

30
smwikipedia

いいえ、大きな違いがあります。 COMには、オブジェクトの作成、メソッドの公開、メモリの管理、タイプ情報の公開、スレッドの管理のための明確に定義されたプロトコルがあります。記述された言語に関係なく、COMサーバーの使用をサポートしない言語は事実上残っていません。

あなたはあなた自身の関数を直接公開することからそれを得ることはありません。これは、C/C++で記述されたプログラム(ヘッダーファイルを読み取ることができる)からのみ使用でき、まったく同じバージョンのC++コンパイラでコンパイルされ、あらゆる種類の相互運用性の問題がないわけではありません。 std :: stringのようなC++クラスオブジェクトを公開するだけの簡単なものは安全ではありません。メモリレイアウトの互換性は保証されておらず、いかなる種類のメモリ所有プロトコルもありません。

OOPはバイナリレベルでの互換性を確保するのが難しいため、COMは継承をサポートしていません。この問題には、.NETのようなVMがすべてのコードに組み込まれるランタイムサポートが必要ですとJava。

34
Hans Passant

Essential COMの最初の章を読むことで、COMを使用する理由が非常によくわかると思います。

簡単にするために、COMは、使用した言語、使用したコンパイラのバージョンに関係なく、バイナリレベルでの互換性を保証します。これは「OOP」のことではなく、DLLからC++クラスを公開することはできますが、「バイナリ互換」ではありません。

8
Baiyan Huang

DLLはWindowsで多くの用途があります。多くの種類のライブラリコードがDLLに格納されています。たとえば、これらの1つは.netアセンブリです。これは別の獣です。

COM DLLは "プレーンバイナリPE DLL"よりも優れていません。COMDLL プレーンDLLでもあるだからです。 DLLをCOMにするものDLLは、おそらく他のものに加えて、特定のコントラクト(署名)[ルックアップエントリIUnknown]、またはいくつかの種類の正規化に一致する特定のエクスポートを公開していますインターフェース[ルックアップエントリ「デュアルインターフェース」] DLL内の特定のオブジェクトのインスタンス化だけでなく、関数名やパラメータータイプなどのサービスの自動検出も可能にします。

スクリプトプログラマーは厳密なタイピングを気にしないため、デュアルインターフェイスにより、スクリプト言語(Web、シェルスクリプト、教育プログラムなどで使用される)へのリンクが非常に便利になります。 COM DLLによって公開されるデュアルインターフェイスにより、スクリプトランタイムは、ユーザーが期待するタイプを正確に照会し、適切なキャストをシームレスにユーザーに実行できます。

この柔軟性により、コンポーネント登録、DCOM(ネットワーク経由の呼び出し)など、巨大なCOMインフラストラクチャ全体を構築することができました。COMコンポーネントをWindowsコンポーネント(WMIなど)やオフィスコンポーネントに提供するのがかなり便利になりました。 ADOなど、他の多くの一般的なインターフェイスがCOMの上に実装されました。

これはすべて問題ありませんが、COMはどのような意味でも「普及」しません。 COM DLLはDLLの少数派です。プレーンDLLと.NET DLLは非常に人気があります。マイクロソフトでは、COMよりも優れた.netインターフェイスを検討しています。多くのunixフリークや他の人は、DLLを完全に悪い考えだと考えています。なぜなら、それはunix共有オブジェクトが常に持っていたのと同じ意味でランタイムリンクサービスを提供しないからです。 Windows開発者であるにも関わらず、SOは優れた代替手段を提供するものだと私は思っています。

5

主な違いは、COMがバイナリ互換性を有効にすることです。

関数を追加/削除して従来のDLLを再構築すると、クライアントアプリケーションはDLLを使用しようとしたときに失敗しますバージョン。

COMは、不変であるため、ビルド間で変更してはならないインターフェイスの概念を導入しました。すべてのCOMオブジェクトは、他のサポートされているインターフェイスへのポインターをオブジェクトに要求するために使用されるQueryInterfaceメソッドを含むIUnknownインターフェイスを実装する必要があります。

COM仕様では、IUnknownインターフェイスがDLL内の常に同じ場所にあることが保証されているため、オブジェクトがより多くのインターフェイスをサポートするように変更されても、QueryInterfaceメソッドを安全に呼び出すことができます。

5
robaker

COMを導入する理由とその背後にある哲学について知りたい場合は、 CPPからCOM を読むことを強くお勧めします

5

COMを考える最良の方法は、COMをあなたとあなたが作成したオブジェクトを使用する人との間の契約であると想像することです。

COMハンドル

  1. リリース間でオブジェクトをバージョン管理する方法
  2. オブジェクトがDLLにあり、名前が変更されている、または別のソースからのものである)場合でも、オブジェクトを検出する方法
  3. オブジェクトを参照および破棄する方法(ヒープに関して)
  4. スレッドが機能することを期待する方法、およびオブジェクトのスレッド/ロックに関するルール

上記の各項目を処理する従来のDLLを作成できる一方で、DLLを出荷するときに期待される契約を明確にする必要があるため、COMは標準になりました。

cOMのルールを使用して、このアーティキュレーションはあなたのために行われます

cOMがオブジェクトを公開するのに対し、より伝統的なDLLは関数を公開するだけであることも正しいです。開発者がCOMで見つかったコントラクトをストレートCでエミュレートしようとすることがよくあります。通常、それらはCOMのクローンの側面をDLLで確認します(たとえば、返されるメソッドが表示されます。関数ポインタの構造体)...私の経験では、COMを使用して公開しない場合DLL場合によっては、特にバージョン管理が画像内にある場合に、ミスの可能性が高まります。

4
stuck

既に投稿されている回答に加えて、COMインターフェイスはバイナリデータオブジェクトをプログラミング言語に依存しない方法で公開します。これにより、これらのオブジェクトのメモリを1つのプロセスアドレス空間に割り当て、別のプロセスアドレス空間で解放できます。マーシャリングとアンマーシャリングのルックアップ。

また、エンコーディングの詳細に注意を払わずに文字列を渡して、nullターミネータがどこにあるかを判断することもできます。 COM文字列はUNICODE文字列としてカウントされます。

IDLをスローし、タイプライブラリをDLLにコンパイルすると、自己記述型のインターフェイスが作成されます。プレーンDLLの場合、外部ドキュメントから、それらが持つメソッドとそれらが取るパラメーターを知る必要があります。

COM標準は、クロスプラットフォームにすることもできます。 Mac版のOfficeはCOMをサポートしており、UnixおよびUnixライクなシステムの実装がありましたが、人気がありませんでした。

3
Ron Ruble