본문 바로가기
Program

[Programming] (윈도우 시스템 프로그래밍) 64bit 기반 프로그래밍 / 에러검출, 에러코드가져오기, GetLastError()

by snwo 2020. 8. 12.

64bit 기반 프로그래밍

64bit 기반 시스템에서 자료형에 대해 고려한 프로그래밍 이다.

LLP64 vs LP64

  • 32bit 시스템과 호환성을 중시한 모델.
운영체제 모델 char short int long pointer
Windows LLP64 1byte 2byte 4byte 4byte 8byte
UNIX LP64 1byte 2byte 4byte 8byte 8byte

64bit 와 32bit 공존의 문제점

int arr[10]={0,};
int arrVal=(int)arr; //데이터 손실

배열 arr 는 포인터다. 배열에서 값을 참조할때 arr[0] 으로 참조하는데, 이것은 *arr 과 같다.
포인터 이므로 8byte 의 크기를 가진다. 하지만 4byteint 로 형변환을 하면 상위 4byte 값의 손실이 일어난다.
(32bit 시스템에서는 에러가 나지 않는다)

Windows 스타일 자료형

  • Polymorphic 자료형 (다형성 자료형)

    #if defined(_WIN64)
      typedef __int64    LONG_PTR;
      typedef unsigned __int64    ULONG_PTR;
      typedef __int64    INT_PTR;
      typedef unsigned __int64    UINT_PTR;
    #else
      typedef long    LONG_PTR;
      typedef unsigned long    ULONG_PTR;
      typedef int     INT_PTR;
      typedef unsigned int    UINT_PTR;
     example
    UINT CalDistance(UINT a,UINT b){return a-b;}
    int _tmain(void){
      INT val1=10;
      INT val2=20;
      _tprintf(_T("distance : %d\n"),
          CalDistance((UINT&val1,(UINT)&val2)
      );
      return 0;
    }

    (주소값의 거리를 계산하는 소스이다.)

    UINT 4byte 이다. 32bit 시스템에서는 잘 계산이 되지만, 64bit 시스템에서는 계산이 안될 가능성이 매우높다.

    이럴때 UINT_PTR 을 사용하면, 32bit 에서는 int (4byte) 로 사용되고, 64bit 에서는 __int64 (8byte) 로 사용이 된다.

     

     

     

  • PTR 을 붙인 이유는 포인터란 뜻이 아니고, 포인터 연산에서 사용하기위한 자료형이라는 뜻이다.(주소값 계산 등)

    GetLastError 함수와 에러코드

    윈도우에서는 오류가 발생했을때, 전역공간에 오류의 원인을 저장한다. 이때 GetLastError 함수로 에러코드값을 가져올 수 있다. (MSDN 에서 에러코드 별 오류원인 확인 가능)

    Windows system 함수를 사용할때 되게 자주 사용해 분기처리를 한다.

    example

    int _tmain(void){
      HANDLE hFile=CreateFile (
          _T("없는파일.DAT"), ~~, ~~, ~~, 
          ~~, ~~, ~~ );
      if(hFile==INVALID_HANDLE_VALUE){
          _tprintf(_T("error code : %d\n"),GetLastError());
      }
      return 0;
    }

    error code : 2

Windows system 함수 (CreateFile) 를 사용하고 오류가 발생했을때 분기해서 에러코드값 출력해주는 소스이다.


GetLastError() 함수는 오류발생을 검출하는 함수가 아니다!

오류검출은 함수마다 다르다. GetLastError() 함수는 단지 에러가 발생했을때 에러코드를 가져오는 함수이다.


(위에서는 CreateFile() 로 파일을 생성하고, 리턴값이 INVALID_HANDLE_VALUE, 대충 핸들반환 실패할때 리턴하는 값일때 분기하여 GetLastError() 함수로 에러코드를 출력하는식으로 오류검출을 한다.)

  • 에러가 발생했을때 바로 GetLastError() 함수를 호출해야 정확한 에러코드를 가져올 수 있다.
  • 만약 첫번째 에러가 발생한 뒤, GetLastError() 함수로 첫번째 에러코드를 가져오기 전,
  • 두번째 에러가 발생해 발생해 다른 에러코드값을 가져올 수 있기 때문이다.

#윤성우 윈도우 시스템 프로그래밍을 BASE로 제작되었습니다.