기타 공부 기록/뇌를자극하는윈도우즈시스템프로그래밍

6강 , Section2. 프로그램 구현 관점에서의 WIN32 vs WIN64/오류의 확인

babystep 2022. 4. 18. 17:16
728x90

 

  • 6 , Section2. 프로그램 구현 관점에서의 WIN32 vs WIN64/오류의 확인
    • 64비트 기반 프로그래밍
      • 64비트 기반 프로그래밍
        • 64비트 시스템을 고려한 프로그래밍으로 자료형에 대해서 고려해야한다.
      • LLP64 vs LP64
        • 32비트 시스템과의 호환성을 중시한 모델
          • 문영제제 
LNIX 
모일 
LLF64 
LF€4 
char 
1바이트 
1바이트 
short 
2바이트 
2바이트 
4바이트 
4바이트 
Icog 
4바이주. 
8바이트 
포인터 
0이트 
8비이트
          • LLP64라도 int 4바이트/ long 4바이트, / 포인터만 8바이트 !
          • LP64 int 4바이트 / long 8 바이트 / 포인트 8바이트
          • ILP : int long pointer
          • LLP : long long pointer

 

  • 운영체제 시스템 환경에 따라서 변수의 크기가 달라진다.
    • L : long 약자 , I : int 약자 , LL (long long) 약자 , P : Pointer 약자
    • LP64 : long pointer 64 값이다.
    • ILP64 : int long , pointer 64비트이다.
    • LLP64 : long long pointer 64비트이다.
    • ILP32 : int Long , pointer 32비트이다.
    • LP 32 : long pointer 32비트이다.
    • 외우기 : 컴퓨터는 16비트 -> 32비트 - >64 비트로 성장 해왔다 뒤에 붙은 숫자는 최종 업그레이드값임으로 ILP64가붙은 시스템에서는 int Long, pointer 제외한 값은 32 비트였던 기본값으로 비트사이즈가 적용된다.  ILP32 경우에서는 16비트였던 기본값으로 적용된다.  아래 표를 살펴보면 규칙을 찾아볼 있다.  char 항상 1바이트(8비트)이고 short또한 항상2바이트(16비트)이다.  시스템환경에 따라 바뀌는 값은 int / long / long long / pointer임으로 해당 값의 변화만 살펴보면 된다.

 

 

 

  • 64비트와 32 비트 공존의 문제점
    • 데이터 손실의 문제
      • #include<stdio.h>

int main(void)

{

int arr[10] = {0,};

int arrVal = (int)arr;   // 데이터 손실이 발생할 있는 위치

printf("pointer : %d \n", arrVal);

return 0;

}

  • arr <- 배열의 이름은 포인터이다.

그렇기 때문에 int *p 선언한 포인터 변수 뿐만 아니라 int arr[] <- arr또한 포인터크기인 8바이트로 처리된다. !

위코드에서 데이터 손실이 발생할 있는 위치에서

32 비트의 경우 포인터가 4바이트이기 때문에 데이터 손실이 없지만

만약 64비트 환경이고 해당 데이터가 4바이트 이상의 크기를 가진 8바이트의 포인터 변수라면 (int) 하게되면 나머지 4바이트가 버려진다.

 

  • Windows 스타일 자료형
    • Polymorphic 자료형  ( 다형성 자료형  /  다형성 : 어떤 사물은 상황에따라서 A 될수도있고 B 될수도 있다 , 사람은 직장에서 팀장이고 집에서는 가장이 될수 있다. 하나가 둘이상의 특성을 지니면 다형적 특성을 지녔다고 한다 ) 
      • LONG_PTR 64비트 환경에서는 __int64 해석되고

그밖에서는 long 으로 해석된다.

  • 해당 이름에 LONG_PTR<<- PTR 들어가서 포인터로 오해할수있지만  포인터가 아니다!
  • 예제 3- 1 ]
    • UINT CalDistance(UINT a, UINT b )

{

return a - b;

}

 

int _tmain(void)

{

INT val1 = 10;

INT val2 = 20;

_tprintf(_T("Position %d %d \n"), (UINT)%val1, (UINT)%val2);

_tprintf(_T("distance : %d \n"), CalDistance( (UINT)&Val1, (UINT)&val2));

 

return 0;

}

  • 해당 예제에서 UINT : 4바이트이다.  ILP64비트 시스템 에서는 예제에서 INT 8비트인데 UINT -> 4바이트로 잘라버리기에 데이터 손실이 생길 있다.
  • defined(MN64) 
typedef UINT-PTR 
*else 
typedef unÅgnedint UINT-PIR: 
#endå
  • 그렇기에 코드처럼 if defined(_WIN64)f 통해서 64환경에서는 UINT_PTR unsigned __int64 대체하고 외에 환경에서는 unsigned int 처리하면 데이터 손실이 없다. 
  • GetLastError 함수와 에러코드
    •    Windows 프로그래밍을 할때 에러를 확인하기 위한 함수
    • GetLastError 호출되기전 가장 최근의 에러 번호를 리턴해준다.
    • 함수호출의 성공 여부 확인의 기본
  • 예제 3-3 ]
    • int _tmain(void)

{

HANDLE hFile =

CreateFile(    // Windows.System 함수

_T("ABC_DAT"), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXSTING, FILE_ATTRIBUTE_NORMAL, NULL);

 

if ( hFile == INVALID_HANDLE_VALUE)

{

_tprintf( _T("error codes  : %d \n "), GetLastError() );

return 0;

}

 

return 0;

}

  • 예제에서 CreateFile 함수를 ABC_DAT파일이 존재하지 않는 상태에서 호출하게되면 hFIle에는 INVLAID_HANDLE_VALUE값이 들어가 있게 된다. 그렇게되면 어떤 에러로 파일을 얻어온건지 알수있는 방법이 GetLastError()이다.
  • 출력결과 ErrorCode 값은 2이며 해당 값은

오류 _ 파일을 찾을 _ 수 없습니다. _

 

2(0x2)

 

시스템은 지정된 파일을 찾을 없습니다. 인것을 위에서 https://docs.microsoft.com/ko-kr/windows/win32/debug/system-error-codes--0-499-  사이트에서 오류번호로 확인가능하다.

 

 

 

728x90