Интегрирование исключений 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 то все станет нормально.