- 6강 , Section2. 프로그램 구현 관점에서의 WIN32 vs WIN64/오류의 확인
- 64비트 기반 프로그래밍
- 64비트 기반 프로그래밍
- 64비트 시스템을 고려한 프로그래밍으로 자료형에 대해서 고려해야한다.
- LLP64 vs LP64
- 32비트 시스템과의 호환성을 중시한 모델
- 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임으로 해당 값의 변화만 살펴보면 된다.
- 출처 : https://www.jinukbaek.com/blog/ko/archives/704
- 출처 2 : https://dojang.io/mod/page/view.php?id=737
- 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바이트로 잘라버리기에 데이터 손실이 생길 수 있다.
- 그렇기에 위 코드처럼 if defined(_WIN64)f를 통해서 64환경에서는 UINT_PTR을 unsigned __int64 로 대체하고 그 외에 환경에서는 unsigned int 로 처리하면 데이터 손실이 없다.
- GetLastError 함수와 에러코드
- Windows 프로그래밍을 할때 에러를 확인하기 위한 함수
- GetLastError가 호출되기전 가장 최근의 에러 번호를 리턴해준다.
- 함수호출의 성공 여부 확인의 기본
- GetLastError 함수 호출
- https://docs.microsoft.com/ko-kr/windows/win32/debug/system-error-codes- 해당 사이트에서 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- 사이트에서 오류번호로 확인가능하다.
'기타 공부 기록 > 뇌를자극하는윈도우즈시스템프로그래밍' 카테고리의 다른 글
7강 : 컴퓨터 구조의 접근방법 (1) (0) | 2022.04.21 |
---|---|
5강 WIN32 vs WIN64 (0) | 2022.04.10 |
4강 : MBCS와 WBCS의 동시지원 (0) | 2022.04.08 |
3강 : Windows에서의 유니코드(UNICODE) (0) | 2022.03.22 |
2 강. 프로그램의 실행과정/하드웨어 구성의 재접근 (0) | 2022.03.07 |