ISurrogate
COM公式ドキュメント
ISurrogate (objidlbase.h) インターフェイスは、既存のサロゲートに新しい DLL サーバーを動的に読み込み、不要になったサロゲートを解放するために使用します。
解説(Remarks)
サロゲートとは、DLL サーバーを読み込むことのできる EXE プロセスであり、コーディングの負担なしに DLL サーバーへ EXE サーバーの利点をもたらします。また、独立した複数の DLL サーバーを単一のプロセス内にまとめて配置できるため、必要となるプロセスの総数を削減できます。DLL サーバーは Microsoft Visual Studio などの標準的な開発ツールを使って容易に記述でき、サロゲートプロセス内で実行することで実行可能形式の実装が持つ利点が得られます。これには、障害の分離、複数のクライアントへの同時サービス提供、および分散環境においてリモートクライアントへサービスを提供できることが含まれます。
メソッド 2
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
ISurrogate::LoadDllServer (objidlbase.h) メソッドは、実装元のサロゲートに DLL サーバーを読み込みます。
| Clsid | GUID* | in | 読み込む DLL サーバーの CLSID。 |
戻り値
このメソッドは標準の戻り値 E_INVALIDARG、E_OUTOFMEMORY、E_UNEXPECTED、および S_OK を返す場合があります。
解説(Remarks)
LoadDllServer を通じて読み込み要求を受け取ると、サロゲートは次の手順を実行する必要があります。
- IUnknown、IClassFactory、および IMarshal をサポートするクラスファクトリオブジェクトを作成します。
- CoRegisterClassObject を呼び出して、新しいクラスファクトリオブジェクトを、要求された CLSID のクラスファクトリとして登録します。
ISurrogate::FreeSurrogate (objidlbase.h) メソッドは、DLL サーバーをアンロードします。
戻り値
このメソッドは標準の戻り値 E_UNEXPECTED、E_FAIL、および S_OK を返す場合があります。
解説(Remarks)
COM は、サロゲートプロセス内で実行中の DLL サーバーがなくなったときに FreeSurrogate を呼び出します。FreeSurrogate が呼び出されると、このメソッドはサロゲートに登録されているすべてのクラスファクトリを適切に取り消し、その後サロゲートプロセスを終了させる必要があります。
サロゲートプロセスは、使用されなくなった DLL サーバーをアンロードするために、CoFreeUnusedLibraries 関数を定期的に呼び出す必要があります。本来はクライアントの責任であるこの処理を、サロゲートプロセスが担います。CoFreeUnusedLibraries は、読み込まれているすべての DLL サーバーに対して DllCanUnloadNow 関数を呼び出します。CoFreeUnusedLibraries は DLL サーバーにおける DllCanUnloadNow の存在と適切な実装に依存するため、アンロードすべきすべての DLL サーバーをアンロードすることは保証されません。すべてのサーバーが DllCanUnloadNow を実装しているわけではなく、また、この関数はフリースレッドの DLL に対しては信頼できません。さらに、サロゲートには、すべての DLL サーバーがなくなったことを通知する手段がありません。しかし COM は、すべての DLL サーバーがアンロードされたことを判定でき、その時点で FreeSurrogate メソッドを呼び出します。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_ISurrogate "{00000022-0000-0000-C000-000000000046}" #usecom global ISurrogate IID_ISurrogate "{}" #comfunc global ISurrogate_LoadDllServer 3 var #comfunc global ISurrogate_FreeSurrogate 4 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数は var(変数直渡し)。varptr 方式にも切替可。#define global IID_ISurrogate "{00000022-0000-0000-C000-000000000046}" #usecom global ISurrogate IID_ISurrogate "{}" #comfunc global ISurrogate_LoadDllServer 3 sptr #comfunc global ISurrogate_FreeSurrogate 4 ; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。 ; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。 ; ※出力/バッファ引数はポインタ方式(token=sptr / 呼び出しは varptr(変数))。