Шаг 317.
Создание внутрипроцессных серверов автоматизации. Обработка ошибок (общие сведения)

    На этом шаге мы приведем общие сведения об обработке ошибок.

    Соглашения о вызовах были рассмотрены на 302 шаге и там же было сказано, что в СОМ-интерфейсах используют соглашения stdcall и safecall. Однако из приведенной там таблицы 1 нельзя понять разницу между этими соглашениями - оба они помещают параметры в стек справа налево, и в обоих стек очищает вызываемый метод. Разница между этими соглашениями заключается в том, что директива safecall не только определяет соглашение о вызовах, но осуществляет обработку ошибок в СОМ-интерфейсах. Сразу же следует оговориться, что описанная ниже обработка ошибок верна как для внутрипроцессного сервера автоматизации (DLL), так и для внепроцессного сервера (ЕХЕ), но во внутрипроцессных серверах автоматизации директива safecall несет еще и информацию о работе со стеком.

    Базовая модель обработки ошибок СОМ заключается в том, что все методы представляют собой функции, возвращающие значение типа HRESULT - целое число. При успешном завершении функции она должна вернуть значение S_OK (0), в случае ошибки - код ошибки. Кроме того, СОМ-сервер может предоставить по запросу клиента дополнительную информацию об ошибке при помощи методов реализованных им интерфейсов ISupportErrorInfo и IErrorInfo. Такой стиль программирования привычен для разработчиков на языке C++, однако плохо согласуется с принятой в Delphi моделью обработки ошибок, связанной с исключениями.

    Именно для устранения этого противоречия в Delphi введен дополнительный тип соглашения о вызовах, задаваемый директивой safecall. По умолчанию он используется для реализации функций объектов ActiveX и при импорте библиотек типов. Впрочем, это поведение можно изменить при помощи диалогового окна Environment Options.


Рис.1. Настройка соглашения о вызовах safecall

    Целевые интерфейсы для соглашения о вызовах safecall выбираются с помощью группы переключателей SafeCall function mapping:

    Как же тогда осуществляется взаимодействие с серверами и клиентами, созданными не в Delphi? Ведь они не поддерживают соглашения о вызовах safecall. Правильно. А ответ прост - компилятор Delphi тоже не компилирует такие методы во что-то уникальное. Они преобразуются в обычные функции, возвращающие значение типа HRESULT и поддерживающие соглашение о вызовах stdcall, но с некоторыми дополнительными изменениями, которые мы рассмотрим в следующих шагах.

    На следующем шаге мы рассмотрим соглашение о вызовах safecall на клиенте.




Предыдущий шаг Содержание Следующий шаг