본문 바로가기

C, C++/WINDOWS VIA C,C++

[WINDOWS VIA C/C++] 01.에러 핸들링

https://www.hanbit.co.kr/store/books/look.php?p_code=B2974835990

 

제프리 리처의 Windows via C/C++(복간판)

이 책은 윈도우 XP, 윈도우 비스타, 윈도우 서버 2008까지 내용을 포괄한다. 이미 윈도우 10이 출시된 지 오래지만 윈도우의 기본 구조는 변하지 않아 아직까지도 이 책은 윈도우 시스템 프로그래

www.hanbit.co.kr

해당 책을 읽고 학습 목적으로 간단하게 정리한 글입니다.


Chapter 01: 에러 핸들링

개요

윈도우 함수의 에러 처리에 대해 알아본다.

윈도우 함수가 return하는 자료형에 따라 실패했을 때 어떤 상황을 반환하는지 확인할 수 있다.

 

대표적인 return 타입

  • VOID: 절대 실패 하지 않는 함수이다.
  • BOOL: 실패하면 0, 성공하면 0이 아닌 값을 반환한다. 따라서 TRUE와 비교하는 것이 아닌 FALSE와 비교하는 것이 옳은 선택이다.
  • HANDLE: 실패하면 NULL을 대개 반환한다. 성공한다면 유효한 오브젝트 핸들 값을 반환한다. 일부 함수는 반환시 -1 값인 INVALID_HANDLE_VALUE를 반환할 수 있기 때문에 문서 확인이 필요하다.
  • PVOID: 실패하면 NULL을 반환한다. 성공하면 데이터를 저장하는 메모리 주소 값을 얻는다.
  • LONG/DWORD: 대부분 개수를 반환하고 실패한다면 0또는 -1을 반환한다. 다만 함수별로 다양할 수 있기 때문에 문서를 살펴보는 것이 필수적이다.

일반적으로 윈도우 함수가 실패하면 실패 사유를 TLS에 저장한다.

이 값을 GetLastError()를 통해서 얻을 수 있다. (대개 에러 상황이 아니라면 값은 0을 반환)

일부 함수들은 성공 사유를 확인해야 하는데 에러와 동일한 메커니즘을 통해 구분한다.

 

디버깅 시에 vs에서 $err,hr을 통해 가장 최근에 발생한 오류를 확인할 수 있다.

 

$err.hr(혹은 $err 둘의 용도가 다름)을 통해 발생한 에러 코드를 확인할 수 있고, 값을 통해 어떤 오류인지도 간단하게 알려준다.

현재는 WSAStartup을 호출하지 않고 소켓 함수를 호출해서 에러가 발생했음을 알 수 있다.

 

vs에는 Error Lookup(오류 조회) 기능이 있다. 도구(Tools)에서 열 수 있다.

에러 값을 입력하면 해당하는 메시지 텍스트를 확인할 수 있다.

 

그리고 만약 발생한 오류를 사용자에게 보여주고 싶다면 FormatMessage 함수를 사용한다.

https://learn.microsoft.com/ko-kr/windows/win32/api/winbase/nf-winbase-formatmessage

 

FormatMessage 함수(winbase.h) - Win32 apps

FormatMessage 함수(winbase.h)는 메시지 문자열의 형식을 지정합니다.

learn.microsoft.com

DWORD FormatMessage(
  [in]           DWORD   dwFlags,
  [in, optional] LPCVOID lpSource,
  [in]           DWORD   dwMessageId,
  [in]           DWORD   dwLanguageId,
  [out]          LPTSTR  lpBuffer,
  [in]           DWORD   nSize,
  [in, optional] va_list *Arguments
);

 

 


SetLastError를 통해 에러 코드를 설정할 수 있다.

일반적으로 존재한다면 이미 정의되어있는 에러 코드를 사용하지만 적절한 것이 없다면 직접 작성할 수도 있다.