COMインターフェイスに使う構造体等は, ヘッダファイルに置いて利用するのが通例である.
製品版のVC++では, ソースに直接「#import "RsvData.dll"」のように書くことでヘッダファイルを自動生成し, COMインターフェイスを使えるようになる. しかし, VC++TkはMFCとATLが削ってあるため, タイプライブラリを見て自作するか, あるいは#importディレクティブを応用して作成することになる. 作成例: RsvData.h
以下は#importディレクティブを使わず, 全ての手続きを直接書いた例である.
#pragma comment(lib, "Ole32.lib")
#pragma comment(lib, "OleAut32.lib")
#include <ObjBase.h>
#include "RsvData.h" // 作成したヘッダファイル.
// 異なるCOMを使いたいときは適宜入れ替える.
main()
{
HRESULT hResult;
IEpgRsv* lpepgrsv = NULL; // インターフェイスポインタ.
// 異なるCOMを使いたいときは適宜書き換える.
CoInitialize(NULL);
hResult = CoCreateInstance(CLSID_EpgRsv,0,CLSCTX_INPROC_SERVER,IID_IEpgRsv,(LPVOID*)&lpepgrsv);
// CLSID_EpgRsv,IID_IEpgRsvの部分はCOMによって適宜書き換える.
// ここにCOMインターフェイスを書いてCOMオブジェクトを操作する.
lpepgrsv->Release();
CoUninitialize();
}
CoInitialize()はスレッド毎に呼ばなければならないが, 一度呼べば複数のCOMを利用してもよい. 最後に対応するCoUninitialize()を必ず呼ぶこと.
インターフェイスポインタ取得(CoCreateInstance()やQueryInterface()など)の成功とRelease()は, 必ず対になるように呼ぶこと. そのため, 未使用とRelease()後のインターフェイスポインタをNULLにするという手段がよく使われる.
個々のCOMインターフェイスは「lpepgrsv->Term();」のようにして呼び出す. エラーは次のように処理する.
hResult = lpepgrsv->DelRsv(2L);
if(FAILED(hResult)) {
// エラー処理
}
なお, FAILED(hResult)と対になるものはSUCCEEDED(hResult)である.
COMインターフェイスで注意しなければいけないのはBSTRの扱いである. BSTRとはUNICODE文字列を指すポインタで, COMオブジェクトとの文字列の受け渡しに使われる.
BSTR文字列をCOMオブジェクトに渡すときは, 呼び出す前にSysAllocString()でメモリを割り当て, 呼び出し後にSysFreeString()で解放しなければならない. 一方, COMオブジェクトからBSTR文字列を受け取ったときは, 呼び出した側がSysFreeString()で解放しなければならない.