Mi comprensión de la misma (en base a algunas páginas de MSDN relacionados) es que mediante la implementación de ISupportErrorInfo
, estás indicando que una o más interfaces en su clase Devuelve información de error llamando SetErrorInfo
, en lugar de sólo el retorno de una insuficiencia HRESULT
.
A tal fin, la implementación de ISuportErrorInfo::InterfaceSupportsErrorInfo
debe devolver S_OK
sólo para los interfaces en su clase que realmente utilizan SetErrorInfo
para devolver información de error a la persona que llama, y sólo esas interfaces.
Por ejemplo, supongamos que tiene una clase que implementa una interfaz que escribió llamada IFoo
que tiene un método DoSomething
. Si otra persona crea una instancia de la clase y llama IFoo::DoSomething
, se supone que deben hacer lo siguiente si DoSomething
devuelve un error HRESULT
(parafraseando desde diversas páginas de MSDN, pero comenzaron desde aquí: http://msdn.microsoft.com/en-us/library/ms221510.aspx):
Call QueryInterface
en el puntero IFoo
para obtener la interfaz ISupportErrorInfo
para el objeto que está implementando IFoo
Si el objeto que se llama no aplicar ISupportErrorInfo
, entonces la persona que llama tendrá para controlar el error según el valor HRESULT
, o pasarlo a la pila de llamadas.
Si el objeto llamado hace aplicar ISupportErrorInfo
, entonces la persona que llama debe llamar ISupportErrorInfo::InterfaceSupportsErrorInfo
, pasando en un REFIID
para la interfaz que devuelve el error. En este caso, el método DoSomething
de la interfaz IFoo
devolvió un error, por lo que pasaría REFIID_IFoo
(asumiendo que está definido) a InterfaceSupportsErrorInfo
.
Si InterfaceSupportsErrorInfo
vuelve S_OK
, entonces la persona que llama sabe en este momento que puede recuperar información más detallada acerca del error llamando GetErrorInfo
.Si InterfaceSupportsErrorInfo
devuelve S_FALSE
, la persona que llama puede suponer que la interfaz llamada no proporciona información de error detallada, y tendrá que confiar en el HRESULT devuelto para descubrir qué sucedió.
La razón de esta API de control de errores tanto confuso/complicado parece ser de flexibilidad (en la medida de lo que puedo decir de todos modos Este es COM después de todo;.). Con este diseño, una clase puede admitir múltiples interfaces, pero no se requiere que todas las interfaces usen SetErrorInfo
para devolver información de error de sus métodos. Puede tener ciertas interfaces seleccionadas en su clase para devolver información de error detallada a través del SetErrorInfo
, mientras que otras interfaces pueden continuar utilizando el normal HRESULT
s para indicar errores.
En resumen, la interfaz ISupportErrorInfo
es una manera de informar el código de llamada que al menos una de las interfaces de sus implementos de clase puede devolver información detallada del error, y el método InterfaceSupportsErrorInfo
cuenta la persona que llama si una interfaz dada es una de esas interfaces . Si es así, la persona que llama puede recuperar la información de error detallada llamando al GetErrorInfo
.
"Si el objeto llamado implementa ISupportErrorInfo, entonces se supone que quien llama a QueryInterface para un ISupportErrorInfo" Probablemente sea un error, porque la persona que llamó acaba de hacer esa llamada para determinar si esta interfaz es compatible en primer lugar? ¿No debería la persona que llama llamar directamente a 'ISupportErrorInfo :: InterfaceSupportsErrorInfo' sin tener que llamar a QI por segunda vez? –
@FelixDombek Estoy de acuerdo. Edité la publicación para eliminar la llamada redundante 'QueryInterface'. –