DirectX异常处理

DirectX Exception handling

本文关键字:异常处理 DirectX      更新时间:2023-10-16

我正在学习DirectX上的rastertek教程,同时学习David Abrahams的《通用组件中的异常安全》(http://www.boost.org/community/exception_safety.html)。

为什么(据任何人所知)异常处理是按照rastertek教程中的方式设置的,它提供了什么级别的保护?

例如:

mhresult = D3D11CreateDeviceAndSwapChain(NULL, D3D_DRIVER_TYPE_HARDWARE, NULL, 0, &mfeatureLevel, 1,
    D3D11_SDK_VERSION, &mswapChainDesc, &mswapChain, &mdevice, NULL, &mdeviceContext);
if (FAILED(mhresult))
{
    return false;
}

如果在对CreateDevice的调用中发生未处理的异常,在我们检查mhresult的结果之前,程序不会崩溃吗?

调用带有HResult返回值的方法还是只调用布尔值的方法有区别吗?

result = mEstablishHW();
if (!result)
{
    return false;
}

是否有一种替代方法可以在不影响性能的情况下提供强大的异常安全性?

DirectX是一个基于COM的API。并且异常不允许跨越COM边界。因此,没有DirectX函数可以抛出。相反,它们使用C样式的返回代码(称为HRESULT)来指示错误。

为了有效地使用DirectX,显然你应该至少学习一些COM的基础知识。但这里有一些技巧可以从一开始,让你的初始代码更安全,并简化调试:

  • 始终检查返回代码。这并不意味着你应该每次都写if/else。编写一个宏来检查HRESULT,在"非S_OK"的情况下中断调试器,并告诉您发生这种情况的文件、行和函数。您还可以将HRESULT转换为可读字符串并输出(在控制台中)
  • 最好检查输出对象是否有效(即不是"NULL"):在您的示例中为mswapChainmdevicemdeviceContext
  • 使用DirectX调试层:D3D11_CREATE_DEVICE_debug
  • 使用图形诊断工具:一个自2012年以来内置在Visual Studio中,Nvidia Nsight也非常好
  • 最后,阅读文档!MSDN并不完美,但是DirectX文档写得很好

无论如何,DirectX并不是开始学习异常安全性的API。也许标准库(比如尝试为类编写正确的swap函数)或Boost(比如文件系统)会更好地实现这一目的。

DirectX不使用异常来报告错误或其他任何事情。DirectX接口是编译器不可知的,使用C++异常会因为ABI的差异而将它们的使用与特定的编译器联系起来。由于ABI的差异,即使是不同版本的Microsoft C++也不兼容。

由于大多数DirectX方法和函数都返回HRESULT值,因此您需要像第一个示例中那样检查错误。然后,如果对您的项目有意义,您可以在自己的代码中抛出异常。