Windows для профессионалов

EXCEPTION_CONTINUE_SEARCH


Приведенные до сих пор примеры были ну просто детскими Чтобы немного встрях нуться, добавим вызов функции:

char g_szBuffer[100];

void FunclinRoosevelt2()
{

char *pchBuffer = NULL;

__try
{

FuncAtude2(pchBuffer);

}

__except (OilFilter2(&pchBuffer))
{

MessageBox(...);

}

}

void FuncAtude2(char *sz)
{

*sz = 0;
}



LONG OilFilter2(char **ppchBuffer)
{

if (*ppchBuffer == NULL)
{

*ppchBuffer = g_szBuffer;
return(EXCEPTION_CONTINUE_EXECUTION);

}

return(EXCEPTION_EXECUTE HANDLER);

}

При выполнении FunclinRoosevelt2 вызывается FuncAtude2, которой передается NULL. Последняя приводит к исключению. Как и раньше, система проверяет выраже ние в фильтре исключений, связанном с последним исполняемым блоком try. В на шем примере это блок try в FunclinRoosevelt2, поэтому для оценки выражения в филь тре исключений система вызываег OilFilter2 (хотя исключение возникло в FuncAtude2).

Замесим ситуацию еще круче, добавив другой блок try-except

char g_szBuffer[100];

void FunclinHoosevelt3()
{

char *pchBuffer = NULL;

__try
{

FuncAtude3(pchBuffer);

}

__except (OilFilter3(&pch8uffer))
{

Message8ox(...);

}

}

void FuncAtude3(char *sz)
{

__try
{

*sz = 0;

}

__except (EXCEPTION_CONTINUE_SEARCH)
{

// этот код никогда не выполняется

...

}

}

LONG OilFilter3(Utar **ppchBuffer)
{

if (*ppchBuffer == NULL)
{

*ppchBuffer = g_szBuffer;

return(EXCEPTION CONTINUE_EXECUTION);

}

return(EXCEPTIQN_EXECUTE_HANDLER);

}

Теперь, когда FuncAtude3 пытается занести 0 по адресу NULL, по-прежнему возбуж дается исключение, но в работу вступает фильтр исключений из FuncAtude3. Значе ние этого очень простого фильтра — EXCEPTIUN_CONTINUE_SEARCH. Данный иден тификатор указывает системе перейти к предыдущему блоку tty, которому соответ ствует блок except, и обработать его фильтр.

Так как фильтр в FuncAtude3 дает EXCEPTION_CONTINUE_SEARCH, система пере ходит к предыдущему блоку try (в функции FunclinRoOsevelt3) и вычисляет eго фильтр OilFilter3. Обнаружив, что значение pchBuffer равно NULL, OilFilter3 меняет его так, чтобы оно указывало на глобальный буфер, и сообщает системе возобновить выпол нение с инструкции, вызвавшей исключение Это позволяет выполнить код в блоке try функции FuncAtude3, но, увы, локальная переменная sz в этой функции не измене на, и возникает новое исключение Опять бесконечный цикл!

Заметьте, я сказал, что система переходит к последнему исполнявшемуся блоку try, которому соответствует блок except, и проверяет его фильтр Это значит, что система пропускает при просмотре цепочки блоков любые блоки try, которым соответствуют блоки finally (а не except). Причина этого очевидна, в блоках finally нет фильтров ис ключений, а потому и проверять в них нечего. Если бы в последнем примере Func Atude3 содержала вместо except, система начала бы проверять фильтры исключений с OilFilter3 в FunclinRroosevelt3

Дополнительную информацию об EXCEPTION_CONTINUE_SEARCH см. в главе 25.



Содержание раздела