在这一节中给大家介绍一下Windows的下的默认的异常处理,标准C++/C#异常,以及他们的主要区别。在后续(二)中将详细介绍Windows的结构化异常的处理与实现。
默认的异常处理
当我们在Windows下开发程序时候,利用的标准的C/C++的标准库,比如利用VS建议App的工程时候,其会自动创建一个主线程。该主线程如果有空指针/除零 操作。整个进程都会退退出,大家想过为什么会退出没有? 其具体原因是下面的代码:
VOID RtlUserThreadStart(PTHREAD_START_ROUTINE pfnStartAddr, PVOID pvParam)
{
__try
{
ExitThread((pfnStartAddr)(pvParam));
}
__except(UnhandledExceptionFilter(GetExceptionInformation()))
{
ExitProcess(GetExceptionCode());
} // NOTE: We never get here.
}
RtlUserThreadStart 是线程在启动的时候执行的默认代码,pfnStartAddr是启动的入口地址,你可以理解成WinMain, Main函数(实际上Windows的C/C++库还会做封装)。try和exception是标准的结构化异常处理,在以后的章节中会详细介绍,自所以会退出,是因为其调用的ExitProcess函数。
标准 C++的异常处理
标准C++的异常一般由于效率的原因,用的比较少,下面是一代代码程序,可以看看标准C++的异常处理,主要是以参数的类型和匹配原则,特别要说明的说标准C++的异常处理中没有finally关键字,是Windows的结构化异常其进行了扩展,引入了__finally关键字。
class Test
{
public:
Test (){cout << "Test ::Constructor\n"; p = new int[20];}
~Test (){cout << "Test ::Destructor\n "; delete p;}
private:
int *p;
};
int _tmain(int argc, _TCHAR* argv[])
{
try
{
// Test code to verify the unwind table.
//Test* test = new Test ();
Test test;
//throw 20;
//throw 'c';
//throw 1.23;
// C++ can not handle the hardware exception which raised by CPU.
//int x = 0;
//int g = 100/ x;
// The following code will not executed.
// cout << "test exception to run..\n" ;
//delete test;
}
catch (int param) { cout << "int exception \n"; }
catch (char param) { cout << "char exception \n"; }
catch (...) { cout << "default exception \n"; }
return 0;
}
标准C#的异常处理
C#的异常就比C++的异常用起来多的多,其关键字是try,throw,catch和finally,具体的含义大家可以查看相关的文档,主要的区别在于C#提供了finally语法,其可以保证已经申请的资源等到释放。
public class EHClass
{
public void ReadFile(int index)
{
try
{
// To run this code, substitute a valid path from your local machine
string path = @"D:\test.txt";
System.IO.StreamReader file = new System.IO.StreamReader(path);
char[] buffer = new char[10];
try
{
file.ReadBlock(buffer, index, buffer.Length);
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message = {1}", path, e.Message);
}
//catch (System.ArgumentException e)
//{
// Console.WriteLine("Error Message = ...........");
//}
finally
{
Console.WriteLine("finally try to close the file");
if (file != null)
{
file.Close();
}
}
}
catch (System.IO.IOException e)
{
Console.WriteLine("Error reading from {0}. Message");
}
catch (System.ArgumentException e)
{
Console.WriteLine("Error Message = ...........");
}
// Do something with buffer...
}
}
class Program
{
static void Main(string[] args)
{
var eh_class = new EHClass();
eh_class.ReadFile(10);
}
}
在下一篇中将详细介绍windows下的结构化异常。