반응형

===============출처 http://jed00.blog.me/140185050403===============





언제부터인가 모르겠는데, 예전에 봤던 함수인데 최근에 보면 그 시그너쳐에 나오는 타입이

DWORD 에서 DWORD_PTR 로, LONG 에서 LONG_PTR 로 바뀌었네요.

처음엔 _PTR 이 붙어서 포인터인줄 알았습니다.

 

DWORD_PTR 의 경우 windows.h 헤더를 까서 따라가보면 결국 아래처럼 typedef 됩니다.

  • 32비트 컴파일 : unsigned long
  • 64비트 컴파일 : unsigned __int64

LONG_PTR 의 경우도 마찬가지로 플랫폼에 따라서 long, __int64 로 됩니다.

보시다시피 이것들은 포인터가 아니라 정수타입입니다.

 

함수의 반환값이나 매개변수 또는 구조체의 데이터멤버가 플랫폼에 의존적인 경우에 사용된다고 할 수 있겠습니다.

그러한 경우에 개념적으로 DWORD 는 DWORD_PTR 로, LONG 은 LONG_PTR 로 대체된다고 볼 수 있겠습니다.

 

근데, 왜 하필 뒤에 _PTR 이라는 포인터라는 의미를 붙였을까요... 헷갈리게...

특히, API 의 함수들을 보면 꼭 포인터랑 관련이 없어도 _PTR 이 붙은 타입을 쓰는 경우가 있습니다.

SetTimer 함수가 대표적인데요...

포인터가 플랫폼에 따라서 크기가 달라지는게 명확해서 _PTR 을 붙인 것을 사용하는 걸까요..

뭔가 다른 이름을 붙였더라면 하고 아쉬운 부분이네요. 주의해야겠습니다.

 

사용하는 경우는 예를 들어 포인터를 정수형값으로 리턴하는 함수가 있다고 합시다.

DWORD         GetAddressToInteger(const void* ptr)  

{

 return (DWORD)ptr;

}

위 함수를 32비트로 컴파일을 하고 32비트 윈도우즈에서 돌린다면 문제없습니다.

하지만 64비트로 컴파일을 해서 64비트 윈도우즈에서 돌릴 때는 문제가 됩니다.

왜냐하면 포인터가 4바이트가 아니라 8바이트이기 때문입니다.

그러면 DWORD 대신 QWORD를 쓸까요?

QWORD GetAddressToInteger(const void* ptr)

{

return (QWORD)ptr;

}

하지만 이 경우엔 32비트환경에서는 쓸데없이 반환값이 8바이트가 되버렸습니다.

 

그래서 32/64 비트 관계없이 컴파일해서 해당 플랫폼에서 맞는 코드 하나를 만들기 위해 DWORD_PTR 을 사용합니다.

DWORD_PTR    GetAddressToInteger(const void* ptr) 

{

return (DWORD_PTR)ptr;

}


BOOL

API 는 C 를 기준으로 제공되므로 C++ 의 bool 타입이 존재하지 않습니다.

하지만, true or false 를 식별할 경우가 많기 때문에 이것을 typedef 로 정의해버렸습니다. 

typedef   int         BOOL;  

특이한 점은 BOOL 은 1바이트가 아니라 int 형으로 정의되고 4바이트입니다.

C++ 의 bool 과 동일하다고 여기면 안됩니다.

 

또 BOOL 의 값으로써 TRUE, FALSE 두 가지가 매크로로써 정의됩니다.

#define TRUE        1 

#define FALSE      0

 

주의할 점은 대부분의 API 함수들의 반환에 포함되는 BOOL 타입의 값은 또는 0 이 아닌 값으로 규정하고 있습니다.

IsWindow 함수의 예를 보면 아래와 같은 시그너쳐를 가지는데,

반환값을 확인할 때 == TRUE 식으로 판단하면 안된다는 것입니다.

BOOL   WINAPI      IsWindow(HWND hWnd);

 

if (IsWindow(hwnd) == TRUE)        // !!!! 잘못된 사용법

if (IsWindow(hwnd) != TRUE)         // !!!! 잘못된 사용법

if (IsWindow(hwnd))                     // 올바른 사용법

if (IsWindow(hwnd) != FALSE)       // 올바른 사용법

if (IsWindow(hwnd) == FALSE)       // 올바른 사용법

 

추가적으로 BOOLEAN 이라는 타입도 있습니다.

typedef    BYTE       BOOLEAN; 

C++ 처럼 1바이트형으로 정의하고 있는데, 실제 이것을 쓰는 곳을 전혀 못봤습니다.

BOOL, bool 과 혼란을 일으키지 않기 위해서라도 안쓰는 것이 좋을 것 같습니다.

 

[출처] [Windows API] 기본자료형|작성자 


C 자료형

대응하는 API 자료형

char unsigned char

CHAR / UCHAR

short unsigned short

SHORT / USHORT

int unsigned int

INT / UINT

long unsigned long

LONG / ULONG

long long unsigned long long

LONGLONG / ULONGLONG1

float

FLOAT

double

DOUBLE

void

VOID

[출처] [Windows API] 기본자료형|작성자 


플랫폼 자료형

이것들은 프로그래밍 언어적 자료형 이전에 플랫폼자체에 대해 부를 수 있는 자료형이라 하겠습니다.

(하지만 플랫폼 자료형이라는 용어는 없습니다. 편의상 이렇게 부릅시다).

 

그런데 프로그래밍 언어적으로 사용되어야 하므로 typedef 로 C자료형으로 정의됩니다. 

API 자료형

크기

정의

비고

BYTE

 8 비트(1 바이트)

 unsigned char

 

WORD

 16 비트(2 바이트)

 unsigned short

word 1 개

DWORD

 32 비트(4 바이트)

 unsigned long

double-word 라는 뜻(word가 2개)

QWORD

 64 비트(8 바이트)

 unsigned __int642

quad-word 라는 뜻(word 가 4개)

[출처] [Windows API] 기본자료형|작성자 


정수를 나타내는 자료형

이것들은 정수자료형이면서도 그 크기를 명확히 표현할 필요가 있을 때 사용되는 용도인 듯 보입니다.

모두 이름에 INT 단어를 가지고 있고 그 크기를 비트단위로 표현한 suffix 를 붙입니다.

정수형은 signed, unsigned 두 가지가 있으므로 unsigned 일 경우 앞에 U prefix 를 붙입니다.

(signed 는 디폴트로 여기는게 컨벤션이라 S prefix 를 붙이지 않는 듯 합니다).

아래와 같이 typedef 로 정의 됩니다.

signed 이름

unsigned 이름

size

INT8

UINT8

1 바이트

INT16

UINT16

2 바이트

INT32

UINT32

4 바이트

INT64

UINT64

8 바이트

 

[출처] [Windows API] 기본자료형|작성자 



플랫폼의존적 자료형

32비트에서는 4바이트, 64비트에서는 8바이트로 정의되는 자료형이 있습니다.

API 자료형

32비트 플랫폼에서

64비트 플랫폼에서

INT_PTR

int

__int64

UINT_PTR

unsigned int

unsigned __int64

LONG_PTR

long

__int64

ULONG_PTR

unsigned long

unsigned __int64

DWORD_PTR

ULONG_PTR

ULONG_PTR

[출처] [Windows API] 기본자료형|작성자 



64비트 관련 자료형

64비트 프로그래밍이 가능해지면서 기존 32비트 크기를 가지는 자료형의 크기에 대해 의문이 생깁니다.

예를 들어, 64bit Windows 에서 long 은 32비트 크기를 가지지만 다른 OS에서는 64비트가 되는 경우가 있다고 합니다.

또한 다른 언어 C# 등에서는 long 이 플랫폼관계없이 64비트크기를 가집니다.

이렇게 일반적인 입장에서 API 32비트자료형크기를 생각해보면 혼란스러울 수밖에 없습니다.

 

그래서 DWORD 나 LONG 의 경우 아래처럼 세분화됩니다.

  • DWORD32, ULONG32 : unsigned int 로 정의되고 32 비트를 뜻한다.
  • DWORD64, ULONG64 : unsigned __int64 로 정의되고 64 비트를 뜻한다.
  • LONG32 : signed int 로 정의되고 32 비트를 뜻한다.
  • LONG64 : __int64 로 정의되고 64 비트를 뜻한다.

DWORDLONG 이라는 타입도 있는데 이것은 unsigned __int64 로 정의됩니다.

 

그런데 64비트플랫폼에서도 DWORD 나 LONG, ULONG 은 여전히 32비트크기를 가집니다.

그리고 LONGLONG, QWORD 등의 64비트용 자료형도 이미 정의되어있습니다.

그런데도 32 나 64 접미사를 붙인 버전이 존재하는 건 이제부터 그것만 쓰라는 것인지

원래 버전도 함께 쓰라는 것인지 알 수가 없습니다.

 

이러한 파생적 자료형정의는 오히려 더 혼란스럽게 하는데 한 몫하는 것 같습니다.

개인적으로 이것들은 안쓰는게 좋아보입니다.

[출처] [Windows API] 기본자료형|작성자 






==============================================================


==========출처 http://blog.naver.com/jidon333/220146250188==========


LPSTR : 

- char* 와 같이 1바이트를 가리키는 포인터이다.

 

LPCSTR : 

- const char* 와 같음

 

LPTSTR : UNICODE (Wide Character) types.

 - 16-bit UNICODE character (WCHAR)를 가리키는 포인터.

 - 유니코드를 지원하기 때문에 2바이트를 가리킨다.

 

LPCTSTR : 

 - const WCHAR* 와 같음








반응형