EXEサーバ - class objectの登録

いちごパック > COM/ActiveXの解説 > EXEサーバ - class objectの登録

COMシステムの登録関数


EXEサーバとして起動されたときには、 CoRegisterClassObject()を呼び出してclass objectをCOMシステムに登録します。 複数登録する場合は、外部からの新規作成待ちを停止した状態で登録し、 すべての登録が終わった状態で外部からの新規作成待ちを開始するようにします。 CoRegisterClassObject()は次の関数です。
HRESULT CoRegisterClassObject(
  REFCLSID rclsid, IUnknown* punk,
  DWORD dwContext, DWORD dwFlags,
  LPDWORD lpdwRegister
  );
rclsidはcoclassのクラスID、punkはクラスオブジェクト、 dwContextはクラスオブジェクトが受け付ける外部アクセス方法の種類、 dwFlagsはクラス登録を制御するフラグ、lpdwRegisterに返されるはIDは登録解除時に使うIDです。
dwContextに渡すフラグはCoCreateInstance()と同じフラグです。例えば次のフラグの組み合わせを渡せます。
CLSCTX_INPROC_SERVERDLLとして実装されたCOMサーバを検索します。
CLSCTX_INPROC_HANDLERインターフェース呼び出し時の中間ハンドラとして、カスタムハンドラを利用可能にします。
CLSCTX_LOCAL_SERVEREXEとして実装されたCOMサーバを検索します。
CLSCTX_REMOTE_SERVERリモートマシンで起動されたCOMサーバを検索します。
dwFlagsには、次のフラグの組み合わせを渡せます。
REGCLS_SINGLEUSEクラスを1回作成したら、外部からそれ以上作成できなくなる
REGCLS_MULTIPLEUSEクラスは何度でも作成できる
REGCLS_SUSPENDEDCoResumeClassObjects()されるまでクラス作成を待つ
REGCLS_SUSPENDEDを指定した場合は、後で次の関数を呼び出す必要があります。
HRESULT CoResumeClassObjects();
class objectをCOMシステムに登録する例は次のようになります。
    CIchigo2Factory factory;
    HRESULT hr;
    DWORD   dwRegister = 0;
    hr = CoRegisterClassObject(
             CLSID_Ichigo2, static_cast<IClassFactory*>(&factory),
             CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &dwRegister);
    if ( SUCCEEDED(hr) ) {
        hr = CoResumeClassObjects();
    }
プロセス終了時には、dwRegisterに返されたIDを渡して次の関数CoRevokeClassObject()を呼び出します。
HRESULT CoRevokeClassObject(DWORD dwRegister);

Embedding処理の例

class objectを登録してメッセージループを実行し、 終了時にclass objectの登録を解除する例は次の通りです。 メッセージループをCoReleaseServerProcess()がゼロを返した時点で打ち切ることで、 CoRevokeClassObject()が呼び出される時点ではCoSuspendClassObjects()された状態になっています。 したがって、EXEサーバのロック数がゼロになってからclass objectが再び参照されて、 EXEサーバのロック数が増えることはありません。
HRESULT RunEmbedding( HINSTANCE hinstEXE )
{
    CIchigo2Factory factory;
    HRESULT hr;
    DWORD   dwRegister = 0;
    hr = CoRegisterClassObject(
             CLSID_Ichigo2, static_cast<IClassFactory*>(&factory),
             CLSCTX_LOCAL_SERVER, REGCLS_MULTIPLEUSE | REGCLS_SUSPENDED, &dwRegister);
    if ( FAILED(hr) ) {
        return hr;
    }
    hr = CoResumeClassObjects();
    if ( SUCCEEDED(hr) ) {
        MSG msg;
        while (GetMessage(&msg, NULL, 0, 0) > 0) {
            TranslateMessage(&msg);
            DispatchMessage(&msg);
        }
    }
    CoRevokeClassObject(dwRegister);
    return hr;
}

関連ページ

  • COM/ActiveXの解説ページ 目次
  • 前の項目: EXEサーバ利用状態の管理
  • 次の項目: クラスのビルドと動作確認