Совместное использование этих двух исключений несколько усложнено. Но в реальных программах необходимо использовать обработку этих двух исключений так как само операционная система будет порождать исключения 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 то все станет нормально. |