2008-10-06 9 views
10

¿Qué significa la interfaz ISupportErrorInfo? Estoy un poco perdido para entenderlo. De MSDN:Implementación de ISupportErrorInfo: ¿qué significa?

Esta interfaz asegura que la información de error se puede propagar en la cadena llamada correctamente. Los objetos de automatización que utilizan el manejo de errores deben implementar ISupportErrorInfo.

Este método indica si una interfaz es compatible o no con la interfaz IErrorInfo .

HRESULT InterfaceSupportsErrorInfo(
    REFIID riid 
); 

¿Qué significa para devolver S_OK en InterfaceSupportsErrorInfo? ¿Deberías devolver S_OK para todas las interfaces? ¿Solo algunos?

Respuesta

17

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.

+0

"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? –

+0

@FelixDombek Estoy de acuerdo. Edité la publicación para eliminar la llamada redundante 'QueryInterface'. –