'Programming/Windows System'에 해당되는 글 2건

  1. 2010.07.07 FormatMessage
  2. 2010.07.07 에러 핸들링
2010. 7. 7. 09:57

윈도우즈 환경에서는 에러번호를 알기 위해 GetLastError()함수를 사용한다.
하지만, DWORD로 넘어오기 때문에 무슨에러인지 알아보기가 어렵다. 그래서 에러번호를 문자열로 바꿔줘야할 필요가 있는데,
이 때 쓰는 함수가 FormatMessage()이다.

OS는 에러 번호를 문자열로 표시 하기위해 테이블을 하나 만들어서 DLL로 관리를 한다.
이 DLL이 Message Dll 이다.

다음은 FormatMessage를 사용하는 예이다.

int main()
{
        setlocale(LC_ALL, "KOREAN");                                                 // printf 에서 unicode 로 한글을 출력 하는 방법이다.
        
         // C++에서는 imbue() 라는 함수로 사용해야 합니다.

        HWND hwnd = CreateWindow( 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 );         //윈도우 생성

        if ( hwnd == 0 )
        {
                DWORD e = GetLastError();         // 실패의 이유를 조사

                printf("실패 : %d\n", e );
  
                TCHAR* s = 0;

                FormatMessage( FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER,
                0,                                             // 메세지 DLL의 핸들
                e,                                             // 에러 번호
                0,                                             // 
                (TCHAR*)&s, 0,                         // 메세지를 담아올 버퍼
                                                               // 실제로는 이중포인터를 보내지만 함수 모양이 포인터로
                                                               // 만들어져 있으므로 형식은 1차 포인터로 보내야 한다.
                0);                                           //


            _tprintf( _T("%s\n"), s );

               LocalFree( s );                         // FormatMessage()는 LocalAlloc()으로메모리를할당한다.

 }
}

'Programming > Windows System' 카테고리의 다른 글

에러 핸들링  (0) 2010.07.07
Posted by 어북어위크
2010. 7. 7. 09:54

표준 C에서는 errno를 통해서 실패의 이유를 알 수 있다.

다음은 예제는 C에서의 에러 처리 기법이다.
int main()
{
        FILE* f = fopen("a.txt", "rt");

        if ( f == 0 )
        {
            printf("error : %d\n", errno);
            printf("%s\n", strerror(errno ));        // errno를 문자열로 바꿔준다.
            perror("FAIL");                                // fprintf( stderr, "FAIL : %s\n", strerror(errno)) 의미
        }
}
여기서 문제는 error가 전역변수 라는 것이다. 지금은 문제가 안되겠지만, 멀티스레드 환경에서는 이 변수를 공유하기 때문에
문제가 될 수 있다.
그래서 윈도우즈 환경에서는 에러정보를 스레드당 한개씩 갖고 있게된다.

윈도우즈 환경에서는 스레드를 만들때마다 구조체가 한개씩 생성된다. 이 구조체를 TEB(Thread Environment Block)라 한다.
즉, 스레드가 10개 생성되면 TEB도 10개가 생성되는 것이다.

이 TEB안에는 모든 스레드별로 다양한 정보가 있는데, 그중에 Last Error Value 정보가 있다. 이Last Error Value가 C에서의 errno역할을 한다. 스레드당 한개씩 생기기 때문에 멀티스레드 환경에서 안전하다고 할 수 있다.

이 때, Last Error Value값을 꺼내오는 함수가 바로 GetLastError()이다.

또, TEB의 전체 내용은 User Memory에 있기 때문에 우리가 접근할 수 있고, WinDBG를 사용하면 TEB의 내용도 확일할 수 있다.

ex) dt nt!_TEB


'Programming > Windows System' 카테고리의 다른 글

FormatMessage  (0) 2010.07.07
Posted by 어북어위크