Поделиться через


Создание исключений программного обеспечения

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

Однако любое условие можно обработать как исключение, если найти это условие в коде и сообщить о нем, вызвав функцию RaiseException. Отмечая ошибки таким образом, можно использовать преимущества структурированной обработки исключений в любом типе ошибки времени выполнения.

Чтобы использовать структурированную обработку исключений с ошибками, выполните следующие действия.

  • Определите собственный код исключения для события.

  • При обнаружении проблемы вызовите функцию RaiseException.

  • Используйте фильтры обработки исключений для проверки определенного кода исключения.

В файле WINERROR.H представлен формат кодов исключения. Чтобы проверить, что определяемый код не будет конфликтовать с существующим кодом исключения, задайте для третьего наиболее значимого бита значение 1. Следует установить четыре наиболее значимых бита, как показано в следующей таблице.

Биты

Рекомендуемый двоичный параметр

Описание

31-30

11

Эти два бита описываются основное состояние кода: 11 = ошибка, 00 = успех, 01 = информация, 10 = предупреждение.

29

1

Бит клиента. Установите значение 1 для пользовательских кодов.

28

0

Зарезервированный бит. (Оставьте значение 0.)

При желании для первых двух битов можно задать параметр, отличный от двоичного параметра 11, хотя параметр "ошибка" подходит для большинства исключений. Помните, что биты 29 и 28 следует установить так, как показано в предыдущей таблице.

Таким образом, для четырех старших битов полученного кода ошибки следует задать шестнадцатеричное значение E. Например, в следующих определениях указываются коды исключения, которые не конфликтуют с кодами исключения Windows. (Хотя может потребоваться проверить, какие коды используются сторонними библиотеками DLL.)

#define STATUS_INSUFFICIENT_MEM       0xE0000001
#define STATUS_FILE_BAD_FORMAT        0xE0000002

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

lpstr = _malloc( nBufferSize );
if (lpstr == NULL)
    RaiseException( STATUS_INSUFFICIENT_MEM, 0, 0, 0);

Если требуется просто создать исключение, можно установить для трех последних параметров значение 0. Три последних параметра полезны при передаче дополнительной информации и установке флага, который запрещает обработчикам продолжать выполнение. Дополнительные сведения о функции RaiseException см. в документации Windows SDK.

Затем можно проверить определенные коды в фильтрах обработки исключений. Например:

__try {
    ...
}
__except (GetExceptionCode() == STATUS_INSUFFICIENT_MEM ||
        GetExceptionCode() == STATUS_FILE_BAD_FORMAT )

См. также

Ссылки

Написание обработчика исключений

Структурированная обработка исключений (C/C++)