デュアル インターフェイスまたはディスパッチ インターフェイスのサポート
ディスパッチ インターフェイスと同様に、すべてのデュアル インターフェイスは IDispatch から継承する必要があります。これは、IDispatch 関数 (GetIDsOfNames、Invoke、GetTypeInfo、GetTypeInfoCount) をすべてアグリゲーター (ADSI) の IDispatch にデリゲートします。 デリゲートするには、拡張オブジェクトがアグリゲーターの IDispatch をクエリし、適切なアグリゲーター メソッドを呼び出し、使用後にポインターを解放する必要があります。
拡張機能をスタンドアロン コンポーネントにできる場合は、それが集計されていることを確認します。 その場合は、ディスパッチ関数をアグリゲーターの IDispatch に再ルーティングします。それ以外の場合は、IDispatch の内部実装を呼び出すか、IADsExtension の実装を呼び出すことができます。
次のコード例は、アグリゲーターの IDispatch に IDispatch 呼び出しを再ルーティングする方法を示しています。 このコード例では、 m_pOuterUnknown メンバー変数がアグリゲーターの IUnknown ポインターに初期化されていることを前提としています。
///////////////////////////////////////////////////
// Delegating IDispatch Methods to the aggregator
///////////////////////////////////////////////////
STDMETHODIMP MyExtension::GetTypeInfoCount(UINT* pctinfo)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetTypeInfoCount( pctinfo );
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::GetTypeInfo(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetTypeInfo( itinfo, lcid, pptinfo );
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::GetIDsOfNames(REFIID riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgdispid)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->GetIDsOfNames( riid, rgszNames, cNames, lcid,
rgdispid);
pDisp->Release();
}
return hr;
}
STDMETHODIMP MyExtension::Invoke(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT*
pvarResult, EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
IDispatch *pDisp = NULL;
HRESULT hr = S_OK;
hr = m_pOuterUnknown->QueryInterface( IID_IDispatch, (void**) &pDisp );
if ( SUCCEEDED(hr) )
{
hr = pDisp->Invoke( dispidMember, riid, lcid, wFlags,
pdispparams, pvarResult, pexcepinfo, puArgErr);
pDisp->Release();
}
return hr;
}
拡張ライターは、拡張オブジェクト内にあるディスパッチ インターフェイスの代わりに、デュアル インターフェイスをサポートすることを強くお勧めします。 デュアル インターフェイスを使用すると、クライアントで vtable アクセスが有効になっている限り、クライアントはより高速にアクセスできます。 詳細については、「ADSI 拡張モデルの遅延バインディングと Vtable アクセス」を参照してください。 現行のモデルでは、デュアル インターフェイスの実装はディスパッチ インターフェイスを実装するよりも難しくはありません。