[Chapter 03] 64비트 기반 프로그래밍

·2022년 10월 19일

※ 아래는 윤성우 뇌를 자극하는 윈도우즈 프로그래밍 한빛미디어(주) 2022년
Chapter03(p.79 ~ 102)을 읽고 정리한 내용입니다.

01 64비트와 32비트


한 번에 송/수신 할 수 있는 데이터 크기와 한 번에 처리할 수 있는 데이터 크기를 기준으로 구분됨

02 LLP64 vs LP64


32비트 환경에서는 int, long, 포인터 모두 4바이트로 표현되나 64비트는 아래와 같이 표현됨

운영체제모델charshortintlong포인터
WindowsLLP641 바이트2 바이트4 바이트4 바이트* 8 바이트
UNIXLP641 바이트2 바이트4 바이트* 8 바이트* 8 바이트

03 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;
    
 #endif

여기서 PTR은 포인터값 기반의 산술연산을 위해 정의된 자료형임을 나타냄
즉, 32비트 시스템과 64비트 시스템의 포인터 정밀도(포인터 크기가) 다르기 때문에 발생할 수
있는 문제를 해결하기 위해 등장한 자료형을 의미

// 예제 3-1

#include <stdio.h>
#include <tchar.h>
#include <windows.h>

UINT CalDistance(UINT a, UINT b)
{
	return b - a;
}

int _tmain(void)
{
	INT val1 = 10;
    INT val2 = 20;
    
    _tprintf(_T("Position %u, %u \n"), (UINT)&val1, (UINT)&val2);
    _tprintf(
    	_T("distance : %u \n"),
        CalDistance((UINT)&val1, (UINT)&val2)
    );
    
    return 0;
}

<실행 결과>
예제 3-1은 WIN32만을 기반으로 한다.

// 예제 3-2
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

UINT_PTR CalDistance(UINT_PTR a, UINT_PTR b)
{
    return a - b;
}

int _tmain(void)
{
    INT32 val1 = 10;
    INT32 val2 = 20;

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

    return 0;
}

UINT_PTR은 Polymorphic 자료형으로 조건부 컴파일 코드를 삽입하지 않아도
32비트 환경이냐 64비트 환경이냐에 따라서 자동으로 선언된다.


04 오류의 확인


오류가 발생했을 때, 이어서 바로 GetLastError 함수를 호출하면 오류의 원인에 해당하는
에러코드를 얻을 수 있다.

// 예제 3-3
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(void)
{
	HANDLE hFile =
		CreateFile(
			_T("ABC.DAT"), GENERIC_READ, FILE_SHARE_READ,
			NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
			NULL);
	if (hFile == INVALID_HANDLE_VALUE)
	{
		_tprintf(_T("error code: %d \n"), GetLastError());
		return 0;
	}
	return 0;
}

<실행 결과>
error code: 2 는 "The system cannot find the file specified"를 의미한다.

// 예제 3-4
#include <stdio.h>
#include <tchar.h>
#include <windows.h>

int _tmain(void)
{
	HANDLE hFile =
		CreateFile(
			_T("ABC.DAT"), GENERIC_READ, FILE_SHARE_READ,
			NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL,
			NULL);

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

	hFile =
		CreateFile(
			_T("ABC2.DAT"), GENERIC_WRITE, FILE_SHARE_READ,
			NULL, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL
			);

	_tprintf(_T("error code: %d \n"), GetLastError());
	return 0;
}

<실행결과>
오류 확인은 오류가 발생한 직후에 바로 해야한다.

위 예제를 이미 한 번 실행한 상태이기 때문에 ABC2.DAT 파일이 생성된 상태이다.
예제를 다시 실행시키면 아래와 같이 두번째 에러 코드가 바뀌게 된다.

error code: 80은 "The file exists"를 의미한다.

0개의 댓글