-
[6] - Error HandlingGraphics 2021. 7. 10. 16:18
Error Handling
이것은 언제나 열을 받게 하는 주제가 아닐 수 없습니다. 그럼에도 불구하고 무슨 일이 일어나고 있는지 판단하려면 싫어도 할 수밖에 없습니다.
C++ 3D DirectX Tutorial [Custom Icons / Error Handling] - YouTube 그리고
hw3d/hw3d at T7-End · planetchili/hw3d (github.com)
planetchili/hw3d
C++ 3D graphics engine under Direct3D 11. Developed in a Planet Chili video tutorial series that can be found on YouTube. https://youtu.be/_4FArgOX1I4 - planetchili/hw3d
github.com
기본적으로 모든 것들을 std::exception에서 상속을 받습니다 이 ChiliException은 기본적으로 두 가지의 정보를 탈취합니다. exception이 발생한 장소의 line number 및 file을 what()이라는 함수로 인쇄할 것입니다.
what()함수의 내부를 살펴보면 다음과 같습니다. 별로 중요한 건 없고 두 가지 정도 유의할 사항 또는 알아두면 기분이 좋은 팁이 있습니다.
함수의 반환 type이 const char*입니다. 첫 줄에 ostringstream 인스턴스를 사용하는 모습을 확인할 수 있는데 이 녀석을 그대로 반환하면 함수의 종결과 동시에 인스턴스가 사라지게 되어 엉뚱한 메모리를 가리키게 될 가능성이 높습니다. 따라서 ChiliException 자체에 whatBuffer라는 muteble을 사용하기로 한 것입니다. type이 mutable인 이유는 이 what함수가 const선언이 되어 있고 what함수 내에서 값을 설정하기 위해서입니다. 이제 Exception을 만들었으니 사용을 해야 할 것입니다.
기존의 Window Class에 Exception Class를 추가했습니다 Constructor를 확인해보면 line과 file그리고 HRESULT hr을 받는다는 사실을 확인할 수 있습니다. line과 file은 Exception class를 정의할 때 무슨 의미인지 알게 되었습니다. 그러나 hr은 무엇일까요? 모르겠습니다. 그냥 Window의 Error Code들은 HRESULT라는 값을 참조한다고 합니다.HRESULT Error Codes | Inside Show | Channel 9 (msdn.com)이 Channel 9은 재미없어 보이긴 하는데 의외로 도움이 많이 되기도 합니다.
그리고 what과 GetType을 Override합니다. 아마 다른 곳에서도 이 Exception을 사용할 생각인가봅니다. 그 밑에 static 함수가 보입니다. TranslateErrorCode라는 이 함수는 Windows Error Code를 받아 해당 Code의 Description string을 보내줄 것입니다.
GetErrorCode는 단순하게 HRESULT hr을 반환하는 함수입니다. 마지막 GetErrorString은 Exception에 저장된 HRESULT hr을 받아서 TranslateErrorCode함수를 호출하여 String을 반환하는 함수입니다. 저도 잘 모르겠습니다. Implementation을 본다면 아주 이해가 빠르지 않을까요? 아님 말고요. 저도 모르겠습니다. 일단 sstream을 include하는 편이 좋겠습니다.
1. constructor는 별 볼일 없습니다. ChiliException의 Constructor를 호출하고 HRESULT를 Initialise합니다.
2. GetType은 그냥 적당한 타입을 반환합니다.
3. TranslageErrorCode는 먼저 Windows Function 중 하나인 FormatMessage를 호출합니다. 모르는 함수가 나오면 무조건 (함수) MSDN을 구글에 치면 나옵니다. 이 함수는 HRESULT를 받아서 Error Code에 대한 Description string을 반환해줍니다. 보면 Parameter에 굉장히 엄청난 것들이 나열된 것을 볼 수 있는데 중요한 것은 MSDN을 둘러보면 다 나와있다는 사실과 hr을 반드시 받아야 한다는 점입니다.
3-1 FORMAT_MESSAGE_ALLOCATE_BUFFER : 말 그대로 Windows Allocate로 메모리에 적당한 버퍼를 할당해줍니다. 그리고 그 공간을 pMsgBuf라는 포인터를 갖다 주는 겁니다. reinterpret_cast<LPSTR>(&pMsgBuf)가 바로 그 역할을 수행하고 있다고 할 수 있습니다. 그리고 이 버퍼에 Error Code String을 포함시킬 수 있겠습니다.
3-2 반환 : FormatMessage는 이 Error String의 길이를 반환합니다. 따라서 길이가 0이라면 뭔가 일이 잘못됐다는 뜻이니 0을 반환할 것입니다. 아니면 잘 진행된 것이니 그대로 진행하도록 합시다. pMsgBuf에 error code의 Description string을 받아왔으면 scope 내에 잠깐 string을 만들어서 pMsgBuf의 값을 저장하고 필요없는 pMsgBuf는 메모리를 해제해줍니다. 물론 HRESULT를 받아서 Error Code에 대한 Description string을 반환해준다고 했으면서 pMsgBuf에 Error code Description이 있다는 말은 저도 잘 납득이 안 갑니다. 여기선 그냥 그렇구나, 하고 넘어가도록 합니다.
이 함수는 Static이기 때문에 일반적인 Error Message를 받을 장소에서 모두 사용가능하다는 장점이 있습니다. 이제 두 개의 Macro를 정의했는데 크게 어려운 내용은 전혀 없습니다.
그리고 그 외 나머지 함수들은 이름대로 직관적인 행동을 수행합니다.
이렇게 활용할 수 있다고 합니다 그리고 CALLBACK은 Win32 API side에서 호출이 되는 함수로 여기서 Exception이 발생해버리면 프로그램이 Crash한다고 하니 주의하는 편이 좋습니다.
'Graphics' 카테고리의 다른 글
[8] - Keyboard (0) 2021.07.12 [7] - ICON (0) 2021.07.10 [5] - Window Framework (0) 2021.07.10 [4] - Mouse and Char (0) 2021.07.03 [3] - Window Messages (0) 2021.07.03