DX::ThrowIfFailed
在D3D12项目中,一般使用宏来定义它
#ifndef ThrowIfFailed
#define ThrowIfFailed(x) \
{ \
HRESULT hr__ = (x); \
std::wstring wfn = AnsiToWString(__FILE__); \
if (FAILED(hr__)) { throw DxException(hr__, L#x, wfn, __LINE__); } \
}//'\'符号用于多行定义
#endif
原理是:
一
接受HRESULT类型的参数输入,然后判断HRESULT是否创建成功,简单来说就是一个错误判断。关于HRESULT类型https://zh.m.wikipedia.org/zh-hans/HRESULT
用’hr__'存储接受的参数x。
二
std::wstring表示定义宽字符,内部通常是wchar_t实现,wchar_t类型占两个字节16bit,char类型占一个字节8bit。wchar_t通常用于扩展字符集,例如汉子,日文等。具体一下wchar_t针对UNICODE编码,string针对ASCII编码。具体函数用法一样。参考请问wstring是什么数据类型?-CSDN社区。
_FILE_ 会在程序编译时包含当前文件名。__LINE__会在程序编译时包含当前行号。
三
AnsiToWString函数的作用就是把string类型的_FILE_ 转换成宽字符,因为文件名或文件路径可能包含扩展字符集的字符导致不能正常显示。
inline std::wstring AnsiToWString(const std::string& str)
{
WCHAR buffer[512];
MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, buffer, 512);
return std::wstring(buffer);
}
MultiByteToWideChar API函数解释参考官方文档https://docs.microsoft.com/en-us/windows/win32/api/stringapiset/nf-stringapiset-multibytetowidechar
四
如果创建失败,即FAILED(hr__)为真,就会抛出异常http://c.biancheng.net/cpp/biancheng/view/3027.html抛出异常之后就会执行throw后面的语句
class DxException
{
public:
DxException() = default;
DxException(HRESULT hr, const std::wstring& functionName, const std::wstring& filename, int lineNumber);
std::wstring ToString()const;
HRESULT ErrorCode = S_OK;
std::wstring FunctionName;
std::wstring Filename;
int LineNumber = -1;
};
DxException类,用于对错误信息进行处理并输出。
std::wstring DxException::ToString()const
{
_com_error err(ErrorCode);
std::wstring msg = err.ErrorMessage();
return FunctionName + L"failed in" + Filename + L"; line" + std::to_wstring(LineNumber) + L"; error: " + msg;
}
ToString函数就是典型的队输出信息进行处理,使其变得易读。
救赎之道,就在其中