2008-10-06 3 views
10

Что означает интерфейс ISupportErrorInfo? Я немного потерял, чтобы понять это. Из MSDN:Реализация ISupportErrorInfo - что это значит?

Этот интерфейс гарантирует, что информация об ошибке может распространяться вверх по цепочке вызовов правильно. Автоматизация объекты, использующие обработку ошибок интерфейсы должны реализовывать ISupportErrorInfo.

Этот метод указывает, поддерживает ли интерфейс интерфейс IErrorInfo .

HRESULT InterfaceSupportsErrorInfo(
    REFIID riid 
); 

Что значит вернуть S_OK в InterfaceSupportsErrorInfo? Если вы вернете S_OK для всех интерфейсов? Лишь некоторые?

ответ

17

Мое понимание этого (на основе некоторых связанных страницах MSDN) является то, что при реализации ISupportErrorInfo, вы подтверждаете, что один или несколько интерфейсов на вашем классе возвращает информацию об ошибке, вызвав SetErrorInfo, в отличие от просто возвращает отказ HRESULT.

С этой целью, ваша реализация ISuportErrorInfo::InterfaceSupportsErrorInfo должна возвращать S_OK только для этих интерфейсов на вашем классе, которые фактически используют SetErrorInfo, чтобы возвратить информацию об ошибке вызывающего абонента, и только этих интерфейсах.

Например, у вас есть класс, который реализует интерфейс, который вы написали, с именем IFoo, который имеет метод DoSomething. Если кто-то создает экземпляр вашего класса и вызывает IFoo::DoSomething, они должны сделать следующее, если DoSomething возвращает ошибку HRESULT (переложения из различных страниц MSDN, но я начал здесь: http://msdn.microsoft.com/en-us/library/ms221510.aspx):

  • вызова QueryInterface на IFoo указателе, чтобы получить интерфейс ISupportErrorInfo для объекта, реализующего IFoo

  • Если вызываемый объект не реализует ISupportErrorInfo, то абонент будет иметь для обработки ошибки на основе значения HRESULT или передать его стек вызовов.

  • Если вызываемый объект действительно осуществляет ISupportErrorInfo, то вызывающий абонент должен вызвать ISupportErrorInfo::InterfaceSupportsErrorInfo, переходящий в REFIID для интерфейса, который возвратил ошибку. В этом случае метод DoSomething интерфейса IFoo возвратил ошибку, поэтому вы должны пройти REFIID_IFoo (при условии, что он определен) до InterfaceSupportsErrorInfo.

  • Если InterfaceSupportsErrorInfo возвращает S_OK, то вызывающий абонент знает на данный момент, что он может извлекать более подробную информацию об ошибке, вызвав GetErrorInfo.Если InterfaceSupportsErrorInfo возвращает S_FALSE, вызывающий может предположить, что вызываемый интерфейс не предоставляет подробную информацию об ошибке, и ему придется полагаться на возвращенный HRESULT, чтобы выяснить, что произошло.

Причина этого несколько запутанной/запутанные обработки ошибок API, как представляется, гибкость (насколько я, как я могу сказать, так или иначе Это является COM в конце концов,.). С помощью этой конструкции класс может поддерживать несколько интерфейсов, но не каждый интерфейс должен использовать SetErrorInfo для возврата информации об ошибках из своих методов. Вы можете иметь определенные, выбирать интерфейсы в своем классе, возвращать подробную информацию об ошибках через SetErrorInfo, в то время как другие интерфейсы могут продолжать использовать обычные HRESULT s для указания ошибок.

В целом, интерфейс ISupportErrorInfo способ сообщить код вызова, что по крайней мере один из интерфейсов вашего класса реализует может вернуть подробную информацию об ошибке, а метод InterfaceSupportsErrorInfo сообщает абоненту, является ли данный интерфейс является одним из этих интерфейсов , Если это так, то вызывающий может получить подробную информацию об ошибке, вызвав GetErrorInfo.

+0

«Если вызываемый объект реализует ISupportErrorInfo, то вызывающий объект должен быть QueryInterface для ISupportErrorInfo« Это, вероятно, ошибка, потому что вызывающий только DID, вызывающий ранее, чтобы определить, поддерживается ли этот интерфейс в первую очередь? Не следует ли, чтобы вызывающий абонент вызывал `ISupportErrorInfo :: InterfaceSupportsErrorInfo` напрямую, не звонив QI во второй раз? – 2014-02-04 00:13:06