exception.c
/*
$RCSfile: exception.c $
$Revision: 1.3 $
$Author: doomer $
$Date: 1997/05/20 12:07:42 $
Copyright (c) 1997 John Dumais
*/
/*
This file is an example to illustrate a technique for
catching exceptions generated in a DLL. We set up an
exception handler that knows how to deal with divide-
by-zero errors. A key point is that the condition which
caused the exception must be cleared before execution
is returned to the application calling this DLL.
Otherwise, the condition which caused the exception will
still exist, and our application will react to the
exceptional condition.
We have used the Windows NT (tm) Structured Exception
Handling mechanism, because the use of C++ exceptions
in functions declared ' extern "C" ' produces undefined
behavior in most compilers.
*/
#include "exception.h"
/*
This is our DLL's exported function. It divides the
value 5 by whatever value is passed into 'divisor'.
If 'divisor' is 0, we will generate an exception.
*/
double functionBlowsUp(double divisor){
double x;
unsigned int fpStatus; /* the fpu status value */
/*
Set up an exception handler
*/
__try{
x=5/divisor;
}
/*
This is our exception filter. The call to 'GetExceptionCode'
will only return valid results when called within parentheses
following the '__except' key word. The value returned from the
function 'evaluateException' detemines what action our filter
will take. If the return value is EXCEPTION_EXECUTE_HANDLER,
we will execute the code in the body of the '__except' block.
Processing then continues with the next statement following
the '__except' block.
If our evaluation function returns EXCEPTION_CONTINUE_SEARCH,
the OS will look for a handler willing to deal with the
exception. In our specific case, the exception will get passed
back to VEE. The default action when the OS can't find a
handler for the exception is to terminate the process.
*/
__except(evaluateException(GetExceptionCode())){
/*
We need to clear the condition which caused the exception.
In the specific case of a divide-by-zero error, we can call
'_clearfp', which will return the floating-point processor
status word and clear the exception condition.
*/
fpStatus=_clearfp();
/*
We pass back a big number to indicate that something
went wrong.
*/
x=9.9e37;
}
return x;
}
/*
This function is called from our exception filter. If the
exception is determined to be a divide-by-zero error, we
return a value that will cause the code in the body of our
'__except' block to execute. Otherwise, we pass back a value
indicating that the OS should look for a handler willing to deal
with the exception.
*/
int evaluateException(DWORD exceptionCode){
int returnVal=EXCEPTION_CONTINUE_SEARCH;
switch(exceptionCode){
case EXCEPTION_FLT_DIVIDE_BY_ZERO:
returnVal=EXCEPTION_EXECUTE_HANDLER;
break;
default:
break;
}
return returnVal;
}
/*
$Log: exception.c $
Revision 1.3 1997/05/20 12:07:42 doomer
another typo
Revision 1.2 1997/05/20 10:51:50 doomer
typo
Revision 1.1 1997/05/20 10:43:40 doomer
Initial revision
*/