将SEH异常映射到NET异常
Win32 SEH异常也可以作为.NET异常捕获。在下面的代码中,托管函数(main)调用本机函数(f),该函数抛出SEH exception exception_INT_DIVIDE_BY_ZERO。大体上,这个异常是在处理System::ExceptionA类型异常的catch块中捕获的。
// ExceptionHandling2.cpp // compile with "cl /clr ExceptionHandling2.cpp" // As I will discuss later, #pargma managed is not recommended; it is only // used to show exceptions thrown across managed / unmanaged boundaries // without using two source files #pragma unmanaged int f() { #pragma managed int main() { catch (System::ExceptionA ex) { System::Console::WriteLine(ex->GetType()->FullName);
如果编译并执行此应用程序,则类型名称System.DivideByZeroException将写入catch块中。大多数SEH异常代码将映射到类型System::Runtime::InteropServices::SEH exception。映射到System.DivideByZeroException是少数几种特殊情况之一。表7-4显示了存在特殊映射的SEH异常。
Win32 Exception Code |
Hex Value |
Managed Exception |
||
EXCEPTION_ |
ACCESS_VIOLATION |
C0000005 |
System: |
:AccessViolationException |
EXCEPTION_ |
NO_MEMORY |
C0000017 |
System: |
:OutOfMemoryException |
EXCEPTION_ |
ARRAY_BOUNDS_EXCEEDED |
C000008C |
System: |
:IndexOutOfRangeException |
EXCEPTION_ |
FLT_DENORMAL_OPERAND |
C000008D |
System: |
:FormatException |
EXCEPTION |
FLT_DIVIDE_BY_ZERO |
C000008E |
System: |
:DivideByZeroException |
EXCEPTION_ |
FLT_INEXACT_RESULT |
C000008F |
System: |
:ArithmeticException |
EXCEPTION_ |
FLT_INVALID_OPERATION |
C0000090 |
System: |
:ArithmeticException |
EXCEPTION_ |
FLT_OVERFLOW |
C0000091 |
System: |
:OverflowException |
EXCEPTION_ |
FLT_STACK_CHECK |
C0000092 |
System: |
:ArithmeticException |
EXCEPTION_ |
FLT_UNDERFLOW |
C0000093 |
System: |
:ArithmeticException |
EXCEPTION_ |
INT_DIVIDE_BY_ZERO |
C0000094 |
System: |
:DivideByZeroException |
EXCEPTION_ |
INT_OVERFLOW |
C0000095 |
System: |
:OverflowException |
EXCEPTION_ |
STACK_OVERFLOW |
C00000FD |
System: |
:StackOverflowException |
All other SEH exceptions |
System::Runtime:: InteropServices::SEHException |
如上表所示,访问冲突(0xC0000005)自动映射到System::AccessViolationException。此异常类型已在.NET 2.0中引入。在.NET的早期版本中,将引发System::null引用异常。由于这是一个中断性更改,您可以切换回原来的行为,配置文件如下所示:
<configuration> <runtime> <legacyNullReferenceExceptionPolicy enabled="1"/> </runtime> </configuration>