结构化异常处理还有另外一种使用方法,就是利用try-finally块,强迫函数在退出前执行一段代码。
NTSTATUS TryFinallyTest()
{
NTSTATUS status = STATUS_SUCCESS;
__try
{
// 做一些事情
return STATUS_SUCCESS;
}
__finally
{
KdPrint(("Enter finally block\n"));
}
}
上面代码块中的__try{}块中,无论运行什么代码(即使是return语句或者触发异常),在程序退出前都会运行__finally{}块中的代码。这样的目的是,在退出前需要运行一些资源回收的工作,而资源回收代码的最佳位置就是放在这个块中。
除此之外,使用try-finally块还可以某种程度上简化代码。比较下面两段代码,其中第一个是没有使用try-finally块的代码,而第二段代码是使用try-finally。可以看出,第二段代码彼第一段代码简化。
void FooTest()
{
NTSTATUS status = STATUS_SUCCESS;
// 执行操作1
status = Foo1(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
// 回收资源
return status;
}
// 执行操作2
status = Foo2(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
// 回收资源
return status;
}
// 执行操作N
status = Foo2(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
// 回收资源
return status;
}
// 返回状态,此状态一般是 STATUS_SUCCESS
return status;
}
以下是使用try-finally 块的代码,实现同样的功能,但可以让代码简化
void FooTest()
{
NTSTATUS status = STATUS_SUCCESS;
__try
{
// 执行操作1
status = Foo1(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
return status;
}
// 执行操作2
status = Foo2(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
return status;
}
// 执行操作N
status = Foo2(...);
// 判断操作是否成功
if(!NT_SUCCESS(status))
{
return status;
}
}
__finally
{
if(!NT_SUCCESS(status))
{
// 回收资源
}
return status;
}
}