Реализация ISupportErrorInfo - что это значит? - PullRequest
11 голосов
/ 06 октября 2008

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

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

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

HRESULT InterfaceSupportsErrorInfo(
  REFIID riid
);

Что означает возвращать S_OK в InterfaceSupportsErrorInfo? Должны ли вы вернуть S_OK для всех интерфейсов? Просто немного?

1 Ответ

19 голосов
/ 06 октября 2008

Насколько я понимаю (основываясь на некоторых связанных страницах 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.

.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...