Мое понимание этого (на основе некоторых связанных страницах 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
.
«Если вызываемый объект реализует ISupportErrorInfo, то вызывающий объект должен быть QueryInterface для ISupportErrorInfo« Это, вероятно, ошибка, потому что вызывающий только DID, вызывающий ранее, чтобы определить, поддерживается ли этот интерфейс в первую очередь? Не следует ли, чтобы вызывающий абонент вызывал `ISupportErrorInfo :: InterfaceSupportsErrorInfo` напрямую, не звонив QI во второй раз? – 2014-02-04 00:13:06