Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курс лекцій.doc
Скачиваний:
15
Добавлен:
03.11.2018
Размер:
1.12 Mб
Скачать

13.3.1.3 Фільтруючий вираз

Фільтуючий вираз часто викликає функцію, яка називається функцією фільтра. Ця функція як правило, приймає один чи кілька параметрів, що описують виключення і вертає одне з трьох можливих значень фільтруючого виразу. Фільтруючий вираз та блок обробки виключення можуть отримати доступ до інформації про виключення, викликаючи наступні функції:

GetExceptionCode() повертає код, який ідентифікує заявлене

виключення

GetExceptionInformation() повертає вказівник на структуру, яка містить детальний опис виключення

Розглянемо приклад використання фільтуючої функції:

#include <except.h>

#include<stdio.h>

#define MY_EXCEPTON 0x0000FACE

void doSomething(void)

{

/*нехай відбулось щось непередбачене і тому заявляємо виключення */

printf(“doSomething():помилковий стан!\n”);

printf(“RaiseException()\n”);

RaiseException(MY_EXCEPTON,

EXCEPTION_CONTINUABLE,0,0);

printf(“мені дозволили продовжувати”);

}

DWORD Exceptionfilter( DWORD dwCode)

{ printf(“фільтр виключення: Код=%ld\n”,dwCode);

if(dvCode== MY_EXCEPTON) return

EXCEPTION_EXECUTE_HANDLER;

else return EXCEPTION_CONTINUE_SEARCH;

/*можна викликати EXCEPTION_CONTINUE_EXECUTION ,що відновить виконання з точки виключення та перерве пошук обробника*/

}

int main(void)

{ try{

dosomathing();

}

except(ExceptionFilter(GetExceptCode()))

{

printf(”виключення перехоплення \n”);

}

return 0;

}

13.3.1.4 Перехоплення виключення процесора

У програмах, що працюють під Windows NT (і частково WIN32s) можна використовувати кадроване управління виключеннями для перехоплення процесорних виключень. Наприклад, за допомогою конструкції _try/_except може бути оброблене відоме general protection fault(загальне порушення захисту). Для цих виключень функція GetExceptioncode() повертає одне з можливих значень, визначених в файлах except.h та winbase.h. От деякі з них:

EXCEPTION_ACCESS_VIOLATION

EXCEPTION_ARRAY_BOUNDS_EXCEEDED

EXCEPTION_FLT_DENORMAL_OPERAND

EXCEPTION_FLT_DIVIDE_BY_ZERO

EXCEPTION_FLT_INEXACT_RESULT

EXCEPTION_FLT_INVALID_OPERATION

EXCEPTION_FLT_OVERFLOW

EXCEPTION_FLT_STACK_CHECK

EXCEPTION_FLT_UNDERFLOW

EXCEPTION_INT_DIVIDE_BY_ZERO

EXCEPTION_INT_OVERFLOW

EXCEPTION_PRIV_INSTRUCTION

EXCEPTION_IN_PAGE_ERROR

EXCEPTION_ILLEGAL_INSTRUCTION

EXCEPTION_NONCONTINUABLE_EXCEPTION

EXCEPTION_STACK_OVER4FLOW

EXCEPTION_INVALID_DISPOSITION

Розглянемо приклад:

#if !defined(STRICT)

#define STRICT

#endif

#include<windows.h>

#include<except.h>

#include<string.h>

DWORD ExceptionFilter( DWORD dwCode,

EXCEPTION_POINTERS *pXcptInfo)

{if(dwCode==STATUS_ACCESS_VIOLATION)

{ return EXCEPTION_EXECUTE_HANDLER;

}

else{

return EXCEPTION_CONTINUE_SEARCH;

}

}

int PASCAL WinMain(HINSTANCE hinstance,

HINSTANCE hPrevInstance, LPSTR lpszCmdline, int nCmdShow)

{ __try

{

char *p=NULL;

strcpy(p,”oh la la!”);

}

__except(ExceptionFilter(GetExceptionCode(),GetExceptionInformation()))

{

MessageBox(NULL,”порушення доступу, завершення”,

“ код обробника виключення...“,MB_OK|MB_TASKMODAL);

}

return 0;

}