COM オブジェクトの作成

COM オブジェクトの作成

コンポーネント オブジェクト モデル (COM) オブジェクトを作成する方法はいくつかある。Microsoft® DirectX® プログラミングでは、次の 2 つの方法が最も一般的に使用されている。

  • 直接的な方法。オブジェクトのクラス識別子 (CLSID) を CoCreateInstance 関数に渡す。この関数は、渡されたオブジェクトのインスタンスを作成し、指定されたインターフェイスへのポインタを返す。
  • 間接的な方法。オブジェクトを作成する DirectX メソッドまたは関数を呼び出す。呼び出したメソッドがオブジェクトを作成し、そのオブジェクトのインターフェイスを返す。この方法でオブジェクトを作成する場合、通常は、返るインターフェイスを指定できない。

オブジェクトを作成する際は、CoInitialize 関数を呼び出してあらかじめ COM を初期化しておく必要がある。間接的にオブジェクトを作成する場合は、オブジェクト作成メソッドによってこの処理が行われる。CoCreateInstance を使ってオブジェクトを作成する必要がある場合は、明示的に CoInitialize を呼び出さなければならない。操作を完了したら、CoUninitialize を呼び出して COM を初期化する必要がある。CoInitialize を呼び出したら、対応する CoUninitialize を呼び出さなければならない。COM を明示的に初期化する必要があるアプリケーションでは、スタートアップ ルーチンで COM を初期化し、クリーンアップ ルーチンで初期化されていない状態に戻すのが一般的である。

CoCreateInstance で COM オブジェクトの新しいインスタンスを作成するには、オブジェクトの CLSID が必要である。公開されている CLSID は、リファレンス ドキュメントまたは該当するヘッダー ファイルに記述されている。CLSID が公開されていない場合は、そのオブジェクトを直接作成することはできない。

CoCreateInstance 関数には 5 つのパラメータがある。DirectX で使う COM オブジェクトを作成する場合は、通常、次のパラメータを設定する。

  • rclsid。このパラメータは、作成するオブジェクトの CLSID に設定する。
  • pUnkOuter。このパラメータは、NULL に設定する。このパラメータは、オブジェクトを結合するときにだけ使う。結合の詳細については、「参考資料」を参照すること。
  • dwClsContext。このパラメータは、CLSCTX_INPROC_SERVER に設定する。この設定は、オブジェクトがダイナミック リンク ライブラリ (DLL) として実装され、アプリケーションの処理の一部として実行されることを示す。
  • riid。このパラメータは、要求するインターフェイスのインターフェイス識別子 (IID) に設定する。この関数は、オブジェクトを作成して、要求されたインターフェイスへのポインタを ppv パラメータに返す。
  • ppv。このパラメータは、関数が戻ったときに riid が指定するインターフェイスに設定されるポインタのアドレスに設定する。この変数を、要求されたインターフェイスへのポインタとして宣言し、パラメータ リスト内のポインタへの参照を (LPVOID *) としてキャストする。

たとえば、次のコードは、Microsoft DirectPlay® ピア オブジェクトの新しいインスタンスを作成して、オブジェクトの IDirectPlay8Peer インターフェイスへのポインタを変数 g_pDP に返している。エラーが発生すると、メッセージ ボックスが表示され、アプリケーションが終了する。

IDirectPlay8Peer*  g_pDP = NULL;
...
CoInitialize( NULL );
...
hr = CoCreateInstance( CLSID_DirectPlay8, NULL, CLSCTX_INPROC_SERVER,
                         IID_IDirectPlay8Peer, (LPVOID*) &g_pDP );

if( FAILED( hr ) ) 
  {
    MessageBox( NULL, TEXT("Failed Creating IDirectPlay8Peer. "),
                  TEXT("DirectPlay Sample"), MB_OK | MB_ICONERROR );
    return FALSE;
  }
...

通常は、オブジェクトを間接的に作成する方が格段に簡単である。オブジェクト作成メソッドにインターフェイス ポインタのアドレスを渡すだけでよい。後は、メソッドによってオブジェクトが作成されて、インターフェイス ポインタが返る。通常、間接的な方法でオブジェクトを作成する場合は、メソッドが返すインターフェイスを選択できない。ただし、オブジェクトの作成方法について、さまざまな事項を指定できる。たとえば、次のコードは、上の IDirect3D9::CreateDevice メソッドを呼び出して、ディスプレイ アダプタを表すデバイス オブジェクトを作成している。このメソッドは、オブジェクトの IDirect3DDevice9 インターフェイスへのポインタを返す。最初の 4 つのパラメータは、オブジェクトを作成するために必要な各種の情報を指定し、5 番目のパラメータはインターフェイス ポインタを受け取る。詳細については、リファレンス ドキュメントを参照すること。

IDirect3DDevice9 *g_pd3dDevice = NULL;
...
if( FAILED( g_pD3D->CreateDevice(D3DADAPTER_DEFAULT,
                                 3DDEVTYPE_HAL,
                                 hWnd,
                                 D3DCREATE_SOFTWARE_VERTEXPROCESSING,
                                 &d3dpp,
                                 &g_pd3dDevice )))

return E_FAIL;