次の方法で共有


デュアル インターフェイスまたはディスパッチ インターフェイスのサポート

ディスパッチ インターフェイスと同様に、すべてのデュアル インターフェイスは IDispatch から継承する必要があります。これは、IDispatch 関数 (GetIDsOfNamesInvokeGetTypeInfoGetTypeInfoCount) をすべてアグリゲーター (ADSI) の IDispatch にデリゲートします。 デリゲートするには、拡張オブジェクトがアグリゲーターの IDispatch をクエリし、適切なアグリゲーター メソッドを呼び出し、使用後にポインターを解放する必要があります。

拡張機能をスタンドアロン コンポーネントにできる場合は、それが集計されていることを確認します。 その場合は、ディスパッチ関数をアグリゲーターの IDispatch に再ルーティングします。それ以外の場合は、IDispatch の内部実装を呼び出すか、IADsExtension の実装を呼び出すことができます。

次のコード例は、アグリゲーターの IDispatchIDispatch 呼び出しを再ルーティングする方法を示しています。 このコード例では、 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 アクセス」を参照してください。 現行のモデルでは、デュアル インターフェイスの実装はディスパッチ インターフェイスを実装するよりも難しくはありません。