Compatibilidad con interfaces duales o de distribución
Al igual que la interfaz de distribución, todas las interfaces duales deben heredar de IDispatch, que delegue todas sus funciones IDispatch (GetIDsOfNames, Invoke, GetTypeInfo, GetTypeInfoCount) a la IDispatch del agregador (ADSI). Para delegar, un objeto de extensión debe consultar el IDispatch del agregador, llamar al método agregador adecuado y liberar el puntero después de su uso.
Si la extensión puede ser un componente independiente, compruebe que se agrega. Si es así, vuelva a enrutar las funciones de envío al IDispatch del agregador; de lo contrario, puede llamar a la implementación interna de IDispatch o puede llamar a la implementación de IADsExtension.
En el ejemplo de código siguiente se muestra cómo volver a enrutar la llamada IDispatch a IDispatch del agregador. En este ejemplo de código se supone que la variable miembro m_pOuterUnknown se ha inicializado en el puntero IUnknown del agregador.
///////////////////////////////////////////////////
// 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;
}
Se recomienda encarecidamente que los escritores de extensiones admitan interfaces duales en lugar de interfaces de envío en sus objetos de extensión. Una interfaz dual permite a un cliente tener un acceso más rápido, siempre y cuando el acceso a vtable esté habilitado en el cliente. Para obtener más información, vea Enlace en tiempo de ejecución frente a acceso vtable en el modelo de extensión ADSI. En función del modelo actual, la implementación de interfaces duales no debe ser más difícil que la implementación de interfaces de distribución.
Comentarios
https://aka.ms/ContentUserFeedback.
Próximamente: A lo largo de 2024 iremos eliminando gradualmente GitHub Issues como mecanismo de comentarios sobre el contenido y lo sustituiremos por un nuevo sistema de comentarios. Para más información, vea:Enviar y ver comentarios de