Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Роджерсон Д. - Основы COM - 2000.pdf
Скачиваний:
412
Добавлен:
13.08.2013
Размер:
2.4 Mб
Скачать

79

double GetCordLength(double BladeSection);

Вместо этого возвращайте из функции HRESULT, а все результаты передавайте через выходные параметры:

HRESULT GetCordLength(/* in */ double BladeSection, /* out */ double* pLength);

HRESULT передает клиенту информацию, необходимую для обнаружения сетевых ошибок. Вызовы функций в Автоматизации (ранее OLE Автоматизация) удовлетворяют этому требованию. Более подробно удаленные компоненты будут рассмотрены в гл. 10.

Определение собственных кодов ошибки

СОМ определяет универсальные коды возврата, таки как S_OK и E_UNEXPECTED. Разработчики интерфейсов ответственны за коды возврата, специфичные для их интерфейсов. HRESULT, содержащий специфичный для интерфейса код возврата, должен также содержать идентификатор средства FACILITY_ITF. Он указывает клиенту, что код специфичен для данного интерфейса.

Хотя смысл кода возврата, отмеченного с помощью FACILITY_ITF, специфичен для возвращающего его интерфейса, само по себе соответствующее число не уникально — возможны только 216 разных значений. Тысячи разработчиков пишут свои компоненты СОМ со своими кодами возврата. Все такие коды помечены с помощью FACILITY_ITF. Поэтому не просто с очень большой вероятностью, но и с гарантией разные интерфейсы придадут разный смысл одним и тем же кодам возврата. Тридцати двух разрядов недостаточно, чтобы дать каждому разработчику ввести свой собственный идентификатор средства, а большая длина HRESULT снизила бы эффективность. В качестве кодов возврата GUID не являются разумной альтернативой длинным целым значениям, поскольку размер GUID слишком велик. Однако, поскольку FACILITY_ITF отмечает каждый код возврата как специфичный для интерфейса, постольку такой код возврата связан с идентификатором интерфейса

(IID).

Для клиента, вызывающего функции интерфейса, возможность конфликта кодов возврата — не проблема. Клиент знает, к кому он обращается, и, таким образом, знает все коды успеха данного интерфейса. Клиент также известна большая часть кодов ошибок. Клиент должен рассматривать любой неизвестный ему код ошибки как E_UNEXPECTED. Однако проблемы начинаются, когда клиент интерфейса сам является компонентом, который пытается без изменения передать возвращаемый код успеха или ошибки своему клиенту. Последний не поймет код, поскольку не знает, к какому первоначальному интерфейсу тот относится.

Например, предположим, что первый клиент вызывает функцию IX::Fx, которая затем вызывает IY::Fy. Если IY::Fy возвращает HRESULT с FACILITY_ITF, то IX::Fx не может передать этот код первому клиенту. Данный клиент знает только о IX — и будет полагать, что HRESULT относится к IX, а не IY. Следовательно, IX::Fx должна транслировать возвращаемые IY значения HRESULT с FACILITY_ITF в такие значения, которые понятны первому клиенту. Для неизвестных ошибок у IX нет иного выбора, кроме как возвращать E_UNEXPECTED. Для кодов успешного завершения IX должен возвращать свои собственные, документированные коды возврата.

Вот некоторые основные правила определения собственных HRESULT:

!" Не назначайте кодам возврата значения из диапазона 0x0000 — 0x01FF. Они зарезервированы для кодов FACILITY_ITF, определенных СОМ.

!" Не возвращайте клиенту коды с признаком FACILITY_ITF без изменения.

!" Используйте универсальные коды успеха и ошибки СОМ всегда, когда только возможно.

!" Избегайте определения собственных HRESULT; вместо этого используйте выходные параметры Вашей функции.

Теперь, когда Вы получили некоторое представление о HRESULT, создадим полный код при помощи макроса MAKE_HRESULT. По заданному признаку критичности, идентификатору средства и коду завершения MAKE_HRESULT создает HRESULT. Вот два примера:

MAKE_HRESULT(SEVERITY_ERROR, FACILITY_ITF, 512);

MAKE_HRESULT(SEVERITY_SUCCESS, FACILITY_ITF, 513);

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

AIRPLANE_E_LANDINGWITHGEARUP

HELICOPTER_S_ROTORRPMGREEN

Сказанного о HRESULT более чем достаточно. Теперь пора снять завесу таинственности с GUID.

Соседние файлы в предмете Программирование на C++