支持双重接口或调度接口

与调度接口一样,所有双接口都必须继承自 IDispatch,后者将所有 IDispatch 函数(GetIDsOfNamesInvokeGetTypeInfoGetTypeInfoCount)委托回聚合器的 IDispatch (ADSI)。 为了委托,扩展对象应查询聚合器的 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 访问。 根据当前模型,实现双接口不应比实现调度接口更困难。