Допустим, Вы хотите создать отказоустойчивое приложение, которое должно рабо тать 24 часа в сутки и 7 дней в неделю. В наше время, когда программное обеспече ние настолько усложнилось и подвержено влиянию множества непредсказуемых фак торов, мне кажется, что без SEH просто нельзя создать действительно надежное при ложение. Возьмем элементарный пример, функцию strcpy из библиотеки С:
char* strcpy(char* strDestination, const char* strSource);
Крошечная, давно известная и очень простая функция, да? Разве она может выз вать завершение процесса? Ну, если в каком-нибудь из параметров будет передан NULL (или любой другой недопустимый адрес), strcpy приведет к нарушению доступа, и весь процесс будет закрыт.
Создание абсолютно надежной функции strcpy возможно только при использова нии SEH
char* RobustStrCpy(char* strDestination, const char* strSource)
{
__try
{
strcpy(strDestination, strSource);
}
except (EXCEPTION_EXECUTE_HANDLER)
{
// здесь ничего на делаем
}
return(strDestination);
}
Все, что делает эта функция, — помещает вызов strcpy в SEH-фрейм. Если вызов strcfiy приходит успешно, RobustStrCpy просто возвращает управление. Если же strcpy генерирует нарушение доступа, фильтр исключений возвращает значение EXCEP TION_EXECIITE_HANDLER, которое заставляет поток выполнить код обработчика. В функции RobublStrCpy обработчик не делает ровным счетом ничего, и опягь Robust StrCpy просто возвращает управление. Но она никогда не приведет к аварийному за вершению процесса1
Рассмотрим другой пример. Вот функция, которая сообщает число отделенных пробелами лексем в строке.
int RobustHowManyToken(const char* str)
{
int nHowManyTokens = -1,
// значение, равное -1, сообщает о неудаче
char* strTemp = NULL;
// предполагаем худшее
__try
{
// создаем временный буфер
strTemp = (char*) malloc(strlen(str) + 1);
// копируем исходную строку во временный буфер
strcpy(strTemp, str);
// получаем первую лексему
char* pszToken = strtok(strTemp, " ");
// перечисляем все лексемы