通常CoCreateInstance()
、COMDLLからオブジェクトをインスタンス化するために使用します。これを行う場合、通常のDLLで行う必要があるように、最初にDLLをロードしてprocアドレスを取得する必要はありません。これは、Windowsが、COM DLLが実装するタイプ、それらが実装されているDLL、およびそれらをインスタンス化する方法を「認識」しているためです。(もちろん、COM DLLが登録されていると仮定します(通常は登録されています)。
使用したいIDogインターフェースを備えたCOMDLLがあるとします。その場合、
dog.idl
interface IDog : IUnknown
{
HRESULT Bark();
};
coclass Dog
{
[default] Interface IDog;
};
myCode.cpp
IDog* piDog = 0;
CoCreateInstance(CLSID_DOG, 0, CLSCTX_INPROC_SERVER, IID_IDOG, &piDog); // windows will instantiate the IDog object and place the pointer to it in piDog
piDog->Bark(); // do stuff
piDog->Release(); // were done with it now
piDog = 0; // no need to delete it -- COM objects generally delete themselves
ただし、これらすべてのメモリ管理機能はかなり汚くなる可能性があり、ATLは、これらのオブジェクトのインスタンス化と管理のタスクを少し簡単にするスマートポインタを提供します。
CComPtr<IDog> dog;
dog.CoCreateInstance(CLSID_DOG);
dog->Bark();
編集:
私が上で言ったとき:
Windowsは、COMDLLが実装するタイプ[...および]それらが実装されているDLLについて「認識」しています。
...私はWindowsがこれをどのように知っているかを正確に理解しました。最初は少しオカルトっぽく見えるかもしれませんが、それは魔法ではありません。
COMライブラリには、ライブラリが提供するインターフェイスとCoClassをリストするタイプライブラリが付属しています。このタイプライブラリは、ハードドライブ上のファイルの形式です。多くの場合、ライブラリ自体と同じDLLまたはEXEに直接埋め込まれています。Windowsは、Windowsレジストリを調べることにより、タイプライブラリとCOMライブラリ自体の場所を認識しています。レジストリのエントリは、ハードドライブ上のDLLが配置されている場所をWindowsに通知します。
を呼び出すとCoCreateInstance
、WindowsはWindowsレジストリでclsidを検索し、対応するDLLを見つけてロードし、COMオブジェクトを実装するDLLで適切なコードを実行します。
この情報はどのようにしてWindowsレジストリに取り込まれますか?COM DLLをインストールすると、登録されます。これは通常、zippy32.exeを実行することによって実行されます。これにより、DLLがメモリに読み込まれ、。という名前の関数が呼び出されDllRegisterServer
ます。COMサーバーに実装されているこの関数は、必要な情報をレジストリに追加します。ATLまたは別のCOMフレームワークを使用している場合、これはおそらく内部で行われているため、レジストリと直接インターフェイスする必要はありません。 DllRegisterServer
インストール時に一度だけ呼び出す必要があります。
/プロセスCoCreateInstance
を介してまだ登録されていないCOMオブジェクトを呼び出そうとすると、次のようなエラーで失敗します。regsvr32
DllRegisterServer
CoCreateInstance
クラスは登録されていません
幸い、これに対する修正はregsvr32
、COMサーバーを呼び出すだけで、再試行することです。