Функция GetExceptionCode - часть 3
Встраиваемую функцию GetExceptionCode можно вызвать только из фильтра ис ключений (между скобками, которые следуют за _except) или из обработчика исклю чений. Скажем, такой код вполне допустим:
__try
{
У = 0;
x = 4 / у;
}
_except
{
{(GetExceptionCode() == EXCEPTION_ACCESS_VIOLATION) (GetExceptionCode() == EXCEPTION_INT_DIVIDE_BY_ZERO)) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEAHCH)
{
switch (GetExceptionCode())
{
case EXCEPTION_ACCESS_VIOLATION:
// обработка нарушения доступа к памяти
...
break;
case EXCEPTION_INT_DIVIDE_BY_ZERO:
// обработка деления целого числа на нуль
...
break;
}
}
Однако GetExceptionCode нельзя вызывать из функции фильтра исключений. Ком пилятор помогает вылавливать такие ошибки и обязательно сообщит о таковой, если Вы попытаетесь скомпилировать, например, следующий код:
__try
{
У = 0;
x = 4 / у;
}
__except (CoffeeFilter())
{
// обрабогка исключения
...
}
LONG CoffeeFilter(void)
{
// ошибка при компиляции: недопустимый вызов GetExceptionCode
return((GetExceptionCode() == EXCFPTION_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
}
Нужного эффекта можно добиться, переписав код так:
__try
{
y = 0;
x = 4 / у;
}
__except (CoffeeFi]ter(GetExceptionCode()))
{
// обработка исключения
...
}
LONG CoffeeFilter(DWORD dwExceptionGode)
{
return((dwExceptionCode == EXCEPTION_ACCESS_VIOLATION) ? EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH);
}
Коды исключений формируются по тем же правилам, что и коды ошибок, опре деленные в файле WinError.h. Каждое значение типа UWORD разбивается на поля, как показано в таблице 24-1.
Биты |
31-30 |
29 |
28 |
27-16 |
15-0 |
Содержимое |
Код степени "тяжести" (severity) |
Кем определен — Microsoft или пользователем |
Зарезервирован |
Код подсистемы (facility code) |
Код исключения |
Значение |
0 = успех 1 = информация 2 = предупреждение 3 = ошибка |
0 = Microsoft 1 = пользователь |
Должен быть 0 (см таблицу ниже) |
Определяется Microsoft |
Определяется Microsoft или пользовате лем |