1. WIN32 VS WIN64
(1) 64 비트와 32 비트
- 한번에 CPU 가 송수신할 수 있는 데이터 크기와 한번에 처리할 수 있는 데이터 크기를 기준으로 32 비트와 64 비트 컴퓨터를 구분짓는다.
(2) 주소값의 크기
- 주소값의 크기는 크면 클수록 좋다. 메모리 공간의 활용이 크만큼 커지기 때문이다. 그러나 주소값의 크기를 무한정 늘릴수는 없는데 왜냐하면 컴퓨터에서 한번에 전송되고 처리되는 데이터의 크기에 따라 주소값의 크기는 종속되기 때문이다. 따라서 32 비트 컴퓨터에서 주소값은 32 비트 (4바이트) 로 표현되며, 64 비트 컴퓨터에서는 64 비트 (8바이트) 로 표현된다.
2. 프로그램 구현 관점에서의 WIN32 VS WIN64
- 마이크로소프트에서는 64 비트 기반의 운영체제를 내놓으면서도 32 비트 시스템과의 호환성을 중시하였다. 그로 인해 프로그래밍 스타일에 대한 가이드를 제시하고 있는데, 이것을 따르는 것이 바로 64 비트 기반 프로그래밍 스타일의 기본이다.
(1) LLP64 VS LP64
- 지금까지 우리는 int, long, 포인터 모두 4바이트로 표현된다고 알고 있었다. 이것은 32 비트 환경에서 WIndows 가 기본자료형과 포인터를 표현하는 방식이다. 그러나 64 비트 컴퓨터에서는 다음과 같이 표현한다.
- LLP64 : Windows 에서 LLP64 라는 데이터 표현 모델은 int, long 은 그대로 4바이트로 표현하고 포인터만 8바이트로 표현한다. 따라서 32 비트 시스템과의 호환성을 중시한 모델이라고 말한다.
- LP64 : UNIX 에서는 LP64 모델을 취하는데, Windows 의 LLP64 모델과 차이가 나는 부분은 long 또한 8바이트로 표현한다는 점이다.
(2) 64 비트와 32 비트 공존의 문제점
- 64 비트 시스템에서는 포인터가 지니고 있는 주소값을 4 바이트 정수형으로 형 변환해서는 안된다.
(3) Windows 스타일 자료형
- 다른 시스템으로의 이식성을 고려한다면 기본 자료형을 사용하거나 프로젝트의 성격 및 특성에 맞게 새로운 이름으로 자료형을 정의하는 것이 좋은 방법이다. 다만 Windows 기반에서의 실행만 고려한다면, 마이크로소프트에서 정의하고 있는 자료형을 사용하는 것도 좋은 선택이 될 수 있다.
- 다음은 마이크로소프트에서 정의하고 있는 많은 양의 자료형 중에서 ANSI 기본 자료형에 대응하는 일부를 보여준다. (첨부표 참고) 이미 앞에서도 문자열 관련 자료형을 몇몇 소개하였다. (TCHAR, LPTSTR, LPCTSTR)
- 위 표를 보면 WIN64 로 넘어가면서, 새로운 자료형 (끝이 32, 64 로 끝나는) 이 상당수 추가되었음을 알 수 있는데, 이는 WIN32 와 WIN64 에서 시스템에 상관없이 동일한 의미를 지니는 자료형을 표현하기 위한 것이다. ~32 형태의 자료형은 시스템에 상관없이 32비트로 표현되고, ~64 형태의 자료형은 시스템에 상관없이 64비트로 표현된다.
* Microsoft C/C++ 에서는 정수 타입으로 크기를 지정해서 선언하는 것이 가능하다. __int(n) 의 형태로 8, 16, 32, 64 를 지정해서 변수를 선언할 수 있다. 즉, __int8, __int16, __int32, __int64 와 같은 타입 선언이 가능하다. 이들은 각각 ANSI 표준의 char, short, int 에 해당한다. 다만 __int64 는 ANSI 표준에 존재하지 않는, Microsoft C/C++ 에만 존재하는 자료형이다. 그러나 기본 자료형과 마찬가지로 사칙연산이 가능하다는 아주 멋진 특성을 지닌다.
- WIN64 로 이전하면서 등장한 자료형들을 사용할 경우, 변수 선언 시 할당된 바이트 수를 정확하고도 쉽게 파악할 수 있어서 도움은 되지만, 그렇다고 WIN32 시절에 정의된 자료형이 WIN64 환경에서 쓸모가 없어진 것은 아니다.
(4) Polymorphic 자료형
- 포인터값 기반의 산술연산을 위해 정의된 자료형이다. 32비트 시스템과 64비트 시스템의 포인터 크기가 다르기 때문에 발생할 수 있는 문제를 해결하기 위해 등장한 자료형이다.
#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;
#endif
* 매크로 _WIN64는 64비트 기반으로 프로젝트 구성시 자동적으로 삽입되는 매크로이다. 32비트 기반으로 프로젝트 구성시 마찬가지로 매크로 _WIN32 가 자동 삽입된다. 따라서 이 매크로는 시스템 환경에 따라서 조건부 컴파일 및 실행하는데 있어서 기준이 된다.
* Polymorphic 자료형을 이용하면 주소값을 64비트 환경에서는 64비트로 32비트 환경에서는 32 비트로 표현할 수 있다.
3. 오류의 확인
- Windows 시스템 함수를 호출하는 과정에서 오류가 발생하면, GetLastError 함수 호출을 통해 오류의 원인을 확인할 수 있다. 많은 수의 Windows 시스템 함수들은 오류가 발생했을 때 NULL 을 반환한다. 반환되는 NULL 값으로 오류가 발생했음을 알 수 있지만, 원인은 알 수가 없다. 오류가 발생했을 때, 이어서 바로 GetLastError 함수를 호출하면 오류의 원인에 해당하는 에러코드를 얻을 수 있다.
DWORD GetLastError(void);
- MSDN 을 참조하면 시스템 에러코드의 종류와 해당 에러코드가 의미하는 바를 알 수 있다.
- 오류 확인은 오류가 발생한 직후에 바로 한다. 에러코드는 Windows 시스템 함수가 호출 될 때마다 갱신되기 때문이다.
[출처] 6장. 64비트 기반 프로그래밍|작성자 나침반
'개발지식창고 > Win32 API' 카테고리의 다른 글
리소스 풀어 헤치기 (0) | 2012.01.13 |
---|---|
특수 폴더 경로 알기 (SHGetSpecialFolderPath) (0) | 2012.01.12 |
작업관리자에서 프로세스 이름 감추기 (0) | 2010.08.22 |
SDK로 구현된 WinMain.cpp 파일의 구성 (0) | 2010.07.30 |