Создание эффективных WIN32-приложений с учетом специфики 64-разрядной версии Windows


Перехват структурных исключений в С++


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

void main()
{

try
{

* (PBYTE) 0 = 0; // нарушение доступа

}

catch ( ..)
{

// этот код обрабатывает исключения, связанные с нарушением доступа

}

// процесс завершается корректно

}

И это прекрасно, так как приложение может корректно справляться с серьезны ми исключениями. Но было бы еще лучше, если бы блок catch как-то различал коды исключений — чтобы мы могли писать, например, такой исходный код

void Functastic()
{

try
{

* (PBYTE) 0 = 0; // нарушение доступа

int x = 0;

x = 5 / x; // деление на нуль

}

catch (StructuredFxception)
{

switch (StructuredExceptionCode)
{

case EXCEPTION_ACCESS_VIOLATION:

// здесь обрабатывается нарушение доступа
break;

case EXCEPTION_INT_OIVIDE_BY_ZERO:

// здесь обрабатывается деление на нуль
break;

default:

// другие исключения мы не обрабатываем throw;
// может, какой-нибудь другой блок catch
// обработает это исключение

break;

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

}

}

}

Так вот, хочу Вас порадовать. В Visual С++ теперь возможно и такое. От Вас потре буется создать С++-класс, используемый специально для идентификации структурных исключений. Например:

#include <eh.h> // для доступа к _set_se_translator

...

class CSE
{

public:

// вызовите эту функцию для каждого потока

static void MapSEtoCE() { _set_se_translator(TranslateSEtoCE); }

operator DWORD() { return(m_er.ExcepUonCude); }

privale:

CSE(PEXCEPTION_POINTERS pep)
{

m_er = *pep->ExceptionRecord;
m_context = *pep->ContextRecord;

}

static void _cdecl TranslateSEtoCE(UINT dwEC, PEXCEPTION_POINTERS pep)
{

throw CSE(pep);

}

private:

EXCEPTION_RECORD m_er;
// машинно-независимая информация ofi исключении

CONTEXT m_context;
// машинно-зависимая информация об исключении




Начало  Назад  Вперед



Книжный магазин