IObjectControl
COM公式ドキュメント
COM+ オブジェクトのコンテキスト固有の初期化およびクリーンアップ処理を定義し、オブジェクトを再利用(リサイクル)できるかどうかを指定します。
メソッド 3
vtbl = vtable インデックス(0始まり)。HSP等からCOMメソッドをインデックス指定で呼ぶ際に使用します。0〜2 は IUnknown。
COM+ オブジェクトがアクティブ化されるたびに、コンテキスト固有の初期化を実行できるようにします。(IObjectControl.Activate)
戻り値
このメソッドは、標準の戻り値 E_INVALIDARG、E_OUTOFMEMORY、E_UNEXPECTED、E_FAIL、および S_OK を返すことがあります。
解説(Remarks)
クライアントがまだアクティブでない COM+ オブジェクトを呼び出すと、COM+ ランタイム環境は自動的にそのオブジェクトをアクティブ化します。これは Just-in-Time Activation(ジャストインタイム アクティベーション) と呼ばれます。IObjectControl をインターフェイスとしてサポートするコンポーネントの場合、COM+ はクライアントのメソッド呼び出しをオブジェクトに渡す前に、オブジェクトの Activate メソッドを呼び出します。
IObjectControl を公開するオブジェクトでは、コンテキスト固有の初期化処理はすべて Activate メソッド内に実装する必要があります。
たとえば、Activate メソッドを使用してオブジェクトのコンテキストへの参照を取得し、それをメンバー変数に格納できます。こうすると、オブジェクトコンテキストを必要とする任意のメソッドから利用できるようになり、使用するたびに新しく取得する必要がなくなります。オブジェクトのコンテキストへの参照を取得した後は、IObjectControl のメソッドを使用して、セキュリティが有効かどうか、オブジェクトがトランザクション内で実行されているかどうか、または呼び出し元が特定のロールに属しているかどうかを確認できます。
オブジェクトのリサイクルを有効にしている場合(オブジェクトに問い合わせるために CanBePooled メソッドを実装している場合)、Activate メソッドは新規に作成されたオブジェクトとリサイクルされたオブジェクトの両方を処理できる必要があります。Activate メソッドが戻った時点で、新しいオブジェクトとリサイクルされたオブジェクトの間に区別できる違いがあってはなりません。
COM+ は、Activate メソッドを呼び出す前(オブジェクトがコンストラクター内にある間)に、IObjectControl を公開するオブジェクトを呼び出すことを明示的に禁止しています。そのような呼び出しは RPC_E_DISCONNECTED エラーを引き起こします。たとえば、オブジェクトがコンストラクター内で自分自身への参照を渡し、その参照が Activate の呼び出しより前にそのオブジェクトを呼び出し返すと、切断エラーが返されます。
また、Activate メソッドを使用してオブジェクトの ISecurityProperty インターフェイスへの参照を取得し、いずれかのメソッドが呼び出される前にオブジェクトの作成者のセキュリティ ID を確認することもできます。
COM+ オブジェクトが再利用(リサイクル)または破棄される前に、必要なクリーンアップを実行できるようにします。
解説(Remarks)
COM+ ランタイム環境は、IObjectControl インターフェイスをサポートするオブジェクトが非アクティブ化されるたびに Deactivate メソッドを呼び出します。オブジェクトが非アクティブ化されるのは、メソッド内で SetComplete または SetAbort を呼び出したメソッドから戻ったとき、そのオブジェクトが実行されていたトランザクションがコミットまたはアボートされたとき、あるいはオブジェクトへの参照を保持している最後のクライアントがその参照を解放したときです。
コンポーネントがリサイクルをサポートしている場合(CanBePooled メソッドから TRUE を返す場合)、Deactivate メソッドを使用して、Activate メソッドが想定している状態にオブジェクトの状態をリセットする必要があります。また、Deactivate メソッドを使用してオブジェクトのコンテキストを解放したり、その他のコンテキスト固有のクリーンアップを行ったりすることもできます。オブジェクトがリサイクルをサポートしている場合でも、Deactivate メソッド内で特定の再利用可能なリソースを解放することが有益な場合があります。たとえば、ODBC は独自の接続プールを提供します。データベース接続をオブジェクトプール内の特定のオブジェクトに結び付けたままにするよりも、他のオブジェクトが使用できる汎用の接続プールにプールする方が効率的です。
COM+ は、deactivate メソッドが戻った後(オブジェクトがデストラクター内にある間)に、IObjectControl を公開するオブジェクトを呼び出すことを明示的に禁止しています。そのような呼び出しは RPC_E_DISCONNECTED エラーを引き起こします。たとえば、オブジェクトが自分自身への参照を渡し、その後 Deactivate が戻った後にそのオブジェクトを呼び出し返すと、切断エラーが発生します。
オブジェクトが非アクティブ化されたときに再利用のためにプールできるかどうかを COM+ ランタイム環境に通知します。
戻り値
オブジェクトを再利用のためにプールできる場合、戻り値は TRUE です。それ以外の場合は FALSE です。
解説(Remarks)
オブジェクトが CanBePooled メソッドから TRUE を返すと、非アクティブ化後に破棄されるのではなくオブジェクトプールに追加できることを COM+ ランタイム環境に通知します。インスタンスが必要になるたびに、新しく作成するのではなくプールから 1 つ取り出されます。
CanBePooled メソッドから TRUE を返しても、オブジェクトがリサイクルされることが保証されるわけではありません。COM+ ランタイム環境にリサイクルを許可するだけです。CanBePooled メソッドから FALSE を返すと、コンポーネントのインスタンスがリサイクルされないことが保証されます。
新しいインスタンスが作成された場合、またはリサイクルされたインスタンスがプールから取り出された場合に、Activate メソッドが呼び出されます。同様に、Deactivate メソッドは、オブジェクトが破棄される場合でもリサイクルのためにプールに戻される場合でも、非アクティブ化されるたびに呼び出されます。
Microsoft 公式リファレンス: 英語 (en-us) · 日本語 (ja-jp) · 原文ソース (GitHub)
HSP用 COM定義
#usecom / #comfunc によるHSPのCOM呼び出し定義。数字は vtbl インデックス(0始まり)。クラスIDが無い場合 #usecom の末尾は "{}"、ある場合は "{CLSID}"。
#define global IID_IObjectControl "{51372AEC-CAE7-11CF-BE81-00AA00A2FA25}"
#usecom global IObjectControl IID_IObjectControl "{}"
#comfunc global IObjectControl_Activate 3
#comfunc global IObjectControl_Deactivate 4
#comfunc global IObjectControl_CanBePooled 5
; ※数字は vtbl インデックス(0始まり)。0/1/2 は IUnknown(QueryInterface/AddRef/Release)。
; ※このインターフェースは直接 CoCreateInstance するクラスIDが無いため "{}"(他メソッド/アクティベーションで取得)。