Интегрирование исключений SEH и C++

Совместное использование этих двух исключений несколько усложнено. Но в реальных программах необходимо использовать обработку этих двух исключений так как само операционная система будет порождать исключения SEH а стандартный функции библиотеки по правилам ANSI будут порождать исключения С++. Используя функцию _set_se_translator у нас есть возможность интегрировать эти два типа исключений.

typedef void (*_se_translator_function)( unsigned int, struct _EXCEPTION_POINTERS* );
_se_translator_function _set_se_translator( _se_translator_function se_trans_func );

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

// Testexception.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"
#include "windows.h"
#include "iostream.h"
#include "eh.h"


class CExcp// класс перехватчик
{
unsigned int m_nCode;
public:
CExcp(unsigned int nCode) : m_nCode(nCode) {};
unsigned int Code() const {return m_nCode;};
};

void SEH_TR(unsigned int nCode, EXCEPTION_POINTERS* pexp) // Получили SEH
{
throw CExcp(nCode);// Вернули C++
}

void ErrorSEH()
{
int *p=0;
*p=0;// Ошибку хотим.
}

void main()
{

_se_translator_function fnOld;// указатель на функцию
fnOld = _set_se_translator(SEH_TR);// перехват
try
{
ErrorSEH();// вызывтать код с ошибкой
}
catch(CExcp& e)// ловим ошибку
{
cout << "Error" << endl;
if (e.Code() ==EXCEPTION_ACCESS_VIOLATION)
cout << "EXCEPTION_ACCESS_VIOLATION" << endl;
}
_set_se_translator(fnOld);// вернуть старую функцию

}

Результат выполнения этой программы будет такой.

Error
EXCEPTION_ACCESS_VIOLATION
Press any key to continue

Попробуйте закоментировать:

//_se_translator_function fnOld;
//fnOld = _set_se_translator(SEH_TR);
............
//_set_se_translator(fnOld);

И теперь результат будет уже критическая ошибка.

Будьте осторожны в версии Release. Установка оптимизации по скорости или по размеру может привести к тому, что этот код не сработает. То есть Вы не перехватите исключение SEH. Попробуйте становить оптимизацию по скорости.  Код не будет работать. А вот отключите ее или поставьте Default то все станет нормально.

 
« Предыдущая статья   Следующая статья »