COM とは Windows 標準の共通のオブジェクトのコンポーネント
COM をつくると Windows 環境で再利用可能なコンポーネントをつくることができる。
言語に依存しない
バイナリ形式
C++ コンパイラがすることを自前でする。
■ 名前
COM は名前を一意にもつ。
これを GUID といい、世界中で開発されたコンポーネントとの重複をふせぐ。
GUID は 128bit の数値ID
which guidgen.exe をつかって guid を生成する。
コンピュータのネットワークカードの uniq id を使って生成をする。
■ COM.の問題点
わかりずらい
■ インターフェイスとは
実装をもたない仕様のこと
C++ でいえば関数ポインタテーブルのこと。
純粋仮想関数の集合
■ IUnknown
すべてのインターフェイスの基底くらす
■ COMクラスとCOMインターフェイスは全くの別物
■ IUnkowon.インターフェイス
インターフェイスの基底
3つの method をもつ
class IUnkowon {
public:
virtual HRESULT QueryInterface( REFID rid, void *ppv ) = 0;
virtual unsigned long AddRef() = 0;
virtual unsigned long Releaes() = 0;
};
POINT
リファレンスカウントは オブジェクトの寿命を管理する方法のひとつ
■ COMInterfaceの定義
COMInterface をつくるには次の方法がある。
■ C++
marshal(整列させる)
C++ 以外の呼び出し元から呼べなくなる。
■ マクロをつかう
言語, OS の差異を吸収できる。
■ MIDL
言語に依存せずに インターフェイスを定義できる
プロキシとスタブを自動生成する。
このため プロセス間通信で必要な処理を自動でしてくれる。
別プロセスの関数を呼ぶということ。
別プロセス間での通信処理をしてくれる。
■ COM.のエラー
1 bit エラー | OK
15 bit エラーコード
16 bit リターンコード
問題点は
関数の呼び出し側が常にエラーコードをチェックする必要があること。
REFERENCE Exception
■ バージョン
COM はバージョンを管理しない
インターフェイスを変更すれば、それは新しい ID をもつインターフェイスとなる
■ COMの概要
COMInterface
特定の COMClass とは完全に独立している。
COM クラス
( COMInterface を実装したもの )
コードの本体。
CLSID をもつ
COM オブジェクト
COM クラスのインスタンスのこと。
StandardInterface
マイクロソフトがプリセットで提供する COM のインターフェイスのこと。
CustomInterface
自作した COM interface のこと。
■ COMClass.をつくる
C++ で COMClass をつくるには次のようにする。
class CoStack : public IStack {
// IUnknown
STDMETHOD ( QueryInterface )( REFIID riid, void *ptr );
// IStack
};
STDMETHODIMP CoStack::QueryInterface( REFIID riid, void *ptr ) {
if ( riid = IID_IUNKOWN ) {
}
else if ( riid = IID_ISTACK ) {
*ptr = this;
}
else {
*ptr = NULL;
}
AddRef();
// ステータスコードを返す
return S_OK;
}
■ オートメーション機構
JScript, VBScript
-------------------------
オートメーション機構 ( Automation )
-------------------------
COM < ---- C, C++ からアクセス
-------------------------
スクリプトツールが 低レベルの COM を利用できないときに使う。
スクリプトと COM (バイナリ)の糊付けのために使う。
スクリプトから利用してもらうには、IDL をつかって interface を記述してあげる。
WARNING
型は Automation 互換型である必要がある。
各プロパティとメソッドは DISPID をもつ。
properties:
[id(1), propget] boolean Empty;
methods:
[id(2)] void Push( long value );
[id(3)] long Pop();
実際によばれるのは IDispatch インタフェイスによって機能する。
interface IDispatch : public IUnkowon{
// 名前(文字列)から DISPID をひく
virtual HRESULT GetIDsOfNames( .... ) = 0;
// プロパティへのアクセスをする
// 一度取得した DISPID は保存される。
virtual HRESULT Invoke();
};
POINT
Invoke は printf に似ている。 interpreter として機能する。
つまり小さなプログラムをかいている。
COMObject のうち
DispatchInterface を提供するものを AutomationServer という。
これを使う コントローラは AutomationController という。
COMObject
は DLL ( InProcessServer ) または EXE( OutOfProcessServer )として実装することもできる。
■ DualInterface
DispatchInterface と VtableInterface の両方をもつもの
呼び出し元は好きな方を選択をできる。
--------------------------------
COMInterface
DualInterface
--------------------------------
■ MetaData
インターフェイスとクラスの情報のこと。 ( reflection )のこと。
あるクラスに対して、どんな機能をもつか調べることができること。
TypeLibrary には COMInterface , COMClass の定義が含まれている。
■ COM.と.C++の違い
C++ : レジストリを利用しない
COM : クラス , interface, TypeLibrary といった静的な情報を保存する。
C++ : new で生成したオブジェクトは delete をつかって破棄をする。
COM : Object 自身を削除することはない。 interface ポインタが不要になったら削除をする。
COM オブジェクト自身が削除をする。
■ TypeLibrary
コンパイルされた IDL ファイルのこと。
プログラムからアクセスできる。
これによって どんな情報をもつか わかることできる。
LIBID という ID をもつ。
スクリプト言語で役にたつ機能
■ ディスパッチインターフェイス
JScript と COM を連携するために使う
プロパティとメソッドを公開するには activeX コントロールにする必要がある。
■ ActiveX
コントロールとは 1つの プログラムのコンポーネントのこと。( GUI の意味ではない )
VBX ---> OLE ---> ActiveX
ActiveX は ディスパッチインターフェイスを通して
プロパティ, メソッド, イベントを 公開する。
イベントとは
名前、パラメータ 戻り値 をもつメソッドのようなもの。
ActiveX のボタンがクリックされると イベントが発生する。
コントロールコンテナによって実装される。
各イベントはメッセージキューにいれられるので非同期に処理される。
ActiveXControl の特徴
DispatchInterface をとおして property, method, event を公開する。
( AutomationObject のこと )
■ コントロールコンテナ
ActiveX コントロールを含むことができるコンポーネントのこと。
コントロールの存在を検索したりするのが仕事。
コントロールカテゴリによって レジストりに分類される。
■ COM.の使い方
// 必要な CLSID は COM の作成者側が提供する。
// 初期化をする( COM ライブラリをロードする )
HRESULT hr = CoInitialize( NULL );
{
// COM オブジェクトを CLSID を指定して作成する
HRESULT hr = CoCreateInstance( CLSID_CoStack, NULL, IID_IUnkown, ptr );
// 指定したインターフェイスを取得する。なければ NULL が返る。
hr = ptr->QueryInterface( IID_STACK, ptr_stack );
}
// 後処理をする
CoUninitialize();
■ クラスオブジェクト(ClassObject)
すべての COMClass は ClassObject をもつ。
これはメタクラスとして機能する。
クラスオブジェクトは システムレジストリに登録されて、オブジェクト生成に利用される。
すべての COMClass と ClassObject は COMサーバ内にある。
COMサーバ( DLL, EXE )内にある、実行可能形式なコードのこと。
IClassFactory を実装する。
class CoStackClassObject : public IClassFactory {
public:
STDMETHOD(CreateInstance)( IUnkowon *outer, REFIID riid, void *ptr );
};
STDMETHOD(CreateInstance)( IUnkowon *outer, REFIID riid, void *ptr )
{
if ( outer != NULL ) {
CoStack *p = new CoStack();
return p;
}
}
■ 言語に非依存
COMInterface は メモリレイアウトが バイナリ形式であるため
言語に依存しない。
COMInterface は関数ポインタのテーブルにすぎない。
C++
クラス定義をみて, コンパイラが仮想関数テーブルを作成してくれる。
C
struct と 関数へのポインタを使って実現できる。
■ 位置に非依存
別プロセスにある場合でも proxy, stub を経由して実行される。
よびだし元 ---> proxy ----> stub ---> COMClass
proxy オブジェクトがパラメータを送信する。
stub オブジェクトがパラメータを受け取り、 COMClass の関数をよびだす。
その結果を proxy に送る。
■ DCOM
RPC( Remote Procedure Call )をベースにしている。
■ COMの使いどころ
呼び出し元と COMClass が別の言語でかかれるときに使う。
■ CORBA
異なるコンピュータ, 言語でかかれたオブジェクト同士間で利用できる。
IDL は実装言語ではなく仕様言語
Proxy パターンを利用して, 言語非依存を実現している。
機種依存をしない形のデータ型をもつ。
CORBA::long は 4byte
sizeof( long ) は機種依存のため 4byte とは限らない。
■ marshaling
marshaling とは異なるマシン間で呼び出しをする場合に
パラメータを適切なバイナリ表現形式にすること。
IIOP