DirectX11 With Windows SDK完整目录html
欢迎加入QQ群: 727623616 能够一块儿探讨DX11,以及有什么问题也能够在这里汇报。git
参考文章:https://blogs.msdn.microsoft.com/chuckw/2012/04/24/wheres-dxerr-lib/github
在龙书11中所使用的HR
宏和dxerr
库是一个比较实用的错误缘由追踪工具。D3D中的某些函数拥有返回值HRESULT
,经过dxerr
库,能够将错误码转换成错误详细信息的字符串。windows
在DirectX SDK中,包含了头文件dxerr.h
和库文件dxerr.lib
,在以往的作法包含了DX SDK后,就能够直接使用dxerr
了。但若是是要编写基于Windows SDK的Direct3D程序,在Windows SDK 8.0以上已经没有了dxerr
库。函数
此时此刻,你仍然有两种选择来脱离对DirectX SDK的依赖:工具
dxerr.h
和dxerr.cpp
源码来编译出dxerr.lib
,或者直接加入你的项目当中;dxerr
库微软已经将dxerr
库开源了,下面的连接能够下载,若是不放心的话,你也能够到上面的参考文章去下载。测试
在我以往的DirectX11项目中,则是从DXUT中拉过来的dxerr
:调试
DXUT Github/Corecode
但要注意的是,因为新的dxerr.h
仅提供了DXTrace
的Unicode字符集版本,须要将原来的__FILE__
替换为__FILEW__
,并在项目属性页中将字符集设置为Unicode。
自Windows SDK 8.0起,HRESULT
值关于DirectX图形API的错误消息字符串映射已经加入到FormatMessage
函数中。咱们能够直接脱离对dxerr
的依赖,并使用该函数来直接获取错误消息字符串。所以,dxerr
库也就没有必要在Windows SDK 8.0以上版本保留了。
鉴于咱们只是要获取错误码对应的字符串信息,这里就简单说起一下该函数的部分用法:
DWORD FormatMessageW( DWORD dwFlags, // [In]FORMAT_MESSAGE系列宏 LPCVOID lpSource, // [In]直接填NULL DWORD dwMessageId, // [In]传入函数异常时返回的HRESULT DWORD dwLanguageId, // [In]语言ID LPTSTR lpBuffer, // [In]用于输出消息字符串的缓冲区 DWORD nSize, // [In]WCHAR缓冲区可容纳元素个数 va_list *Arguments // [In]直接填NULL );
这里我将dxerr
中DXTraceW
函数的实现进行了修改,因为如今错误码信息为中文,为此也顺便把错误窗口和输出也汉化了。只须要包含Windows.h
和sal.h
就可使用。
函数原型:
// ------------------------------ // DXTraceW函数 // ------------------------------ // 在调试输出窗口中输出格式化错误信息,可选的错误窗口弹出(已汉化) // [In]strFile 当前文件名,一般传递宏__FILEW__ // [In]hlslFileName 当前行号,一般传递宏__LINE__ // [In]hr 函数执行出现问题时返回的HRESULT值 // [In]strMsg 用于帮助调试定位的字符串,一般传递L#x(可能为NULL) // [In]bPopMsgBox 若是为TRUE,则弹出一个消息弹窗告知错误信息 // 返回值: 形参hr HRESULT WINAPI DXTraceW(_In_z_ const WCHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr, _In_opt_ const WCHAR* strMsg, _In_ bool bPopMsgBox);
函数实现:
HRESULT WINAPI DXTraceW(_In_z_ const WCHAR* strFile, _In_ DWORD dwLine, _In_ HRESULT hr, _In_opt_ const WCHAR* strMsg, _In_ bool bPopMsgBox) { WCHAR strBufferFile[MAX_PATH]; WCHAR strBufferLine[128]; WCHAR strBufferError[300]; WCHAR strBufferMsg[1024]; WCHAR strBufferHR[40]; WCHAR strBuffer[3000]; swprintf_s(strBufferLine, 128, L"%lu", dwLine); if (strFile) { swprintf_s(strBuffer, 3000, L"%ls(%ls): ", strFile, strBufferLine); OutputDebugStringW(strBuffer); } size_t nMsgLen = (strMsg) ? wcsnlen_s(strMsg, 1024) : 0; if (nMsgLen > 0) { OutputDebugStringW(strMsg); OutputDebugStringW(L" "); } // Windows SDK 8.0起DirectX的错误信息已经集成进错误码中,能够经过FormatMessageW获取错误信息字符串 // 不须要分配字符串内存 FormatMessageW(FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, hr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), strBufferError, 256, nullptr); WCHAR* errorStr = wcsrchr(strBufferError, L'\r'); if (errorStr) { errorStr[0] = L'\0'; // 擦除FormatMessageW带来的换行符(把\r\n的\r置换为\0便可) } swprintf_s(strBufferHR, 40, L" (0x%0.8x)", hr); wcscat_s(strBufferError, strBufferHR); swprintf_s(strBuffer, 3000, L"错误码含义:%ls", strBufferError); OutputDebugStringW(strBuffer); OutputDebugStringW(L"\n"); if (bPopMsgBox) { wcscpy_s(strBufferFile, MAX_PATH, L""); if (strFile) wcscpy_s(strBufferFile, MAX_PATH, strFile); wcscpy_s(strBufferMsg, 1024, L""); if (nMsgLen > 0) swprintf_s(strBufferMsg, 1024, L"当前调用:%ls\n", strMsg); swprintf_s(strBuffer, 3000, L"文件名:%ls\n行号:%ls\n错误码含义:%ls\n%ls您须要调试当前应用程序吗?", strBufferFile, strBufferLine, strBufferError, strBufferMsg); int nResult = MessageBoxW(GetForegroundWindow(), strBuffer, L"错误", MB_YESNO | MB_ICONERROR); if (nResult == IDYES) DebugBreak(); } return hr; }
如今的HR宏变成了这样:
// ------------------------------ // HR宏 // ------------------------------ // Debug模式下的错误提醒与追踪 #if defined(DEBUG) | defined(_DEBUG) #ifndef HR #define HR(x) \ { \ HRESULT hr = (x); \ if(FAILED(hr)) \ { \ DXTraceW(__FILEW__, (DWORD)__LINE__, hr, L#x, true);\ } \ } #endif #else #ifndef HR #define HR(x) (x) #endif #endif
测试效果以下:
在调试输出窗口也能够看到:
DirectX11 With Windows SDK完整目录
欢迎加入QQ群: 727623616 能够一块儿探讨DX11,以及有什么问题也能够在这里汇报。