実装のための基礎知識

とりあえず時間がないので簡単に。
「Visual C++6.0によるCOMプログラミング」を流し読みした結果なので、間違っているかも^^;

COMコンポーネントの表現

GUID

128ビットの値。
必ず一意になる。

プログラムID

GUIDと関連づくID。
PDIからGUIDを検索することが可能。

IUnknowインターフェイス

COMオブジェクトは必ずこのインターフェイスを実装する。
このインターフェイスは、純粋仮想関数が定義されている。
関数 概要
QueryInterface CoCreateInstance()APIが呼び出されたときに、呼び出される。
このAPIを使い、インターフェイスが公開されているか問い合わせが行われる。
Addref 参照回数をインクリメントする。
Release 参照カウンタをディクリメントする。
AddRefとReleaseは1対1の関係で呼び出される必要がある。
なぜなら、COMでは、参照カウンタが0になった時点でメモリからインスタンスが消滅する。
そのため、参照カウンタが0にならない場合、いつまでもメモリ上にインスタンスが存在することになる。

ただし、VC++のスマートポインタなどでは、自動的に、AddRef,Releaseの呼びだしが行われるため、スマートポインタを利用している場合は、気にする必要がない。

CoCreateInstance

コンポーネントのインスタンスを生成するためのAPI。

クラスファクトリ

ほかのCOMコンポーネントの新スタンスを作成するためのコンポーネント。

IDispatchインターフェイス

オートメーションの基礎になるインターフェイス。
このインターフェイスを利用すると、コンポーネントの持つ機能(状態や動作)を実行時に知ることが可能。
コンパイル時に、コンポーネントの機能についての検査(機能の名称、型などの検査)を行わない。
そのため、クライアント側でIDispatchをサポートしていれば、コンポーネントそのものや詳細な情報がなくても クライアントの開発が可能。
提供する機能は、Invoke関数で公開される。
IDispatchを実装する場合は、以下の仮想関数を実装する
関数 概要
GetTypeInfoCount TypeInfoの数
GetTypeInfo TypeInfoを取得
GetIDsOfNames インターフェイスの機能の名前に対するIDを取得する。
Invoke コンポーネントが公開する機能を呼び出す関数。 GetIDsOfNamesで取得したDISPID(プロパティやメソッドのID) を使って、コンポーネントの機能を呼び出す。

デュアルインターフェイス

ディスプレイインターフェイスと同等の機能を直接公開するインターフェイスの2つを公開する方法。
IDispatchではパフォーマンスがよくない場合などに、IDispatchだけでなく、ほかのインターフェイスも公開し、 そのインターフェイスでIDispatch経由で公開していた機能と同等な機能を直接公開する。

MFCの利用

非GUIのクラスは利用可能らしい。
STl等を利用するのが望ましいようだ。
ただし、ALTを使う場合のCComObject等は別。

BSTR

文字列はBSTR型で扱う。
VC++であれば、変換用の関数やマクロ、クラスが用意されている。
Windows APIを使っても変換が可能。

VARIANT

これは、どんな値でも入れることが可能な型である。
値部分は共有体で宣言されている。
基本的な使い方は、メンバのvtで、どの型に値が入っているかを判断し、値を取り出す。

SAFEARRAY

言語依存せずに安全に配列を受け渡すための型。
この型を利用するには、決まった関数を利用する。
関数 概要
SafeArrayCreate SAFEARRAYを作成
SafeArrayDestroy SAFEARRAYを削除
SafeArrayGetElement 指定された要素の取得
SafeArrayPutElement 指定された要素に代入
SafeArrayGetLBound 配列の最下位インデックスを取得
SafeArrayGetUBound 配列の最上位インデックスを取得

IDL

インターフェイス定義書。
MIDL(専用コンパイラ)でコンパイルすることで生成される。

包含と集約