COM dll を作成してから何年も経ちました。いくつかの COM インターフェイスから継承するいくつかのクラスを作成しましたが、それをテストしたいと思います。GUID をどこかに配置してから regsvr32 に登録する必要があることはわかっていますが、どのような手順が必要ですか?
編集: 申し訳ありませんが、私は C++ を使用していることを忘れていました。
COM dll を作成してから何年も経ちました。いくつかの COM インターフェイスから継承するいくつかのクラスを作成しましたが、それをテストしたいと思います。GUID をどこかに配置してから regsvr32 に登録する必要があることはわかっていますが、どのような手順が必要ですか?
編集: 申し訳ありませんが、私は C++ を使用していることを忘れていました。
新しいATLCOMプロジェクトを作成するには、次の手順に従います。
新しいdllを作成しましたが、空です。COMオブジェクトを追加するには、次のようにします。
オブジェクトにインターフェースを実装させたい場合
PS:別のフォルダーに同じ名前の新しいATLプロジェクトを作成し、カスタマイズしたファイルを追加する方がはるかに簡単です。ウィザードはいくつかのタスクを実行し、いくつかのカスタマイズされたファイルを作成します。
ファイルごとに追加するのが難しい大きなプロジェクトの場合も同じようにしますが、新しいプロジェクトにファイルを追加する代わりに、新しいプロジェクトから古いプロジェクトに設定をコピーし、ウィザードが作成したファイルを追加します。 stdafx.hなどのヘッダーを修正して、新しい設定をマージします。
PPS:dllでMFCをサポートする場合は、ATLプロジェクトを選択する代わりに、MFC /MFCDllを選択する必要があります。ATL Simple Objectを追加すると、ウィザードはプロジェクトにATLサポートを追加するように要求します。
DllGetClassObjectという関数を作成してエクスポートする必要があります。その関数は、「クラス ファクトリ」の割り当てを担当します。これも作成する必要があり、COM オブジェクトのインスタンスを割り当てることができます。IClassFactoryを実装する必要があります。
難しいことではありません。別の方法は、理論的にはこれを行うATL(xhanttの回答を参照)を使用することですが、実際にはそれは本当に混乱です。どういうわけか、さらに複雑な抽象化レイヤー内に COM の複雑さをカプセル化することに成功しています。たとえば、DLL 間でオブジェクトを移動しようとして頑張ってください。
ただし、ATL ウィザードを実行して、 を宣言する方法の例を確認することもできますDllGetClassObject
。実装IClassFactory
は非常に簡単です。オブジェクトをニュースアップする 1 つのメソッドだけです。
次に、DLL を登録する必要があります。つまり、キーをレジストリに入れます。このregsvr32
ツールは、ユーザーの支援がなければこれを行うことができません。DllRegisterServerと呼ばれる別の関数を作成してエクスポートする必要があります。これがすべての面倒な作業を行います。regsvr32
DLL をロードし、検索してDllRegisterServer
呼び出すだけです。
繰り返しますが、ATL にはこれを実装する方法がありますが、DLL のリソースに埋め込まれた .rgs ファイルに格納されたレジストリ変更命令でいっぱいの一種のスクリプトを読み取ることによって実行します。このファイルに何らかの構文エラーを誤って入力すると、登録は警告なしで失敗します。
繰り返しになりますが、実際には、数行のコードを記述してレジストリを微調整する方が簡単であることに気付くかもしれません。詳細はこちら。
代わりに C# を使用した場合、これらの問題は発生しません。すべてが非常にきれいにカプセル化されています。COM オブジェクトを開発するためのツールとしては、実際には C++ よりもはるかに優れています。
ソリューションをビルドすると、dll が自動的に登録されます。また、_i.c と .h ファイルの 2 つのファイルが作成されます。
dll をテストするには、サンプル アプリケーションを作成します。
サンプル Win32 アプリケーションを作成します。main 関数を持つ win32 アプリケーションの cpp ファイルに _i.c と .h を含めます。
CoInitialize() を呼び出します。
インターフェイス ポインター CComPtr pMyInterface = NULL を宣言します。// _i.c で IMyInterface が宣言されている場所
インスタンス pMyInterface.CoCreateInstance(CLSID_MyClass) を作成します。// CLSID_MyClass は CoClass を表す GUID
です
インターフェイスに存在する API を呼び出す
CoUnInitialize(); を呼び出します。