My friends, my life, my style - James S.F. Hsieh

3/05/2009

x64 Part 5: 在 Windows 64 (LLP64) 下會改變大小的幾個 type

ANSI C 定義的 type Specify standard memory model size_t: 用來描述一結構的大小 (數值型態 無號數) ptrdiff_t: 用來描述兩指標間的距離 (數值型態 有號數) intptr_t, uintptr_t: 整數的指標型態 (指標型態) time_t: 描述一段時間的總秒數 (數值型態 有號數)

當中最值得拿來提的是 size_t, 因為, sizeof 的回傳值與 STL 標準 allocator 的計量單位都是 size_t, 因此, 只要使用標準的 allocator, 則 STL 中所有的 size_type define size_t, 而 capacity, size, count 都是以 size_t 做為計量單位.

// definition of file xmemory #define _SIZT size_t #define _PDFT ptrdiff_t // definition of std::allocator typedef _SIZT size_type; typedef _PDFT difference_type; // definition of std::vector typedef typename _Alloc::size_type size_type; typedef typename _Alloc::difference_type difference_type;

Win32 API 定義的 type INT_PTR, UINT_PTR, WPARAM (數值型態) LONG_PTR, ULONG_PTR, LPARAM, LRESULT (數值型態) SHANDLE_PTR, HANDLE_PTR (數值型態)

PINT_PTR, PUINT_PTR (指標型態) PLONG_PTR, PULONG_PTR (指標型態) HANDLE, HMODULE, HINSTANCE, HGDIOBJ ... (指標型態) HWND, HGDIOBJ, HDC ... (指標型態)

Windows 中有許多將指標轉換成數值的方式在 API 間傳遞, 以 thread 的 message queue 為例, 以下是訊息處理函式的定義:

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)

LRESULT, WPARAM, LPARAM 通常可以用來傳遞數值或是指標, 該 type 的大小在 32bit 和 64bit 的環境中, 大小就有所不同, 值得一提的是 HWND, HGDIOBJ, HDC 等 GDI32 的 type 也改變了大小, 但是它們都有特別的定義(如下), 但是 HWND 的數值似乎永遠都不大於 32 個 bit, 即使是 Spy ++ 64bit (spyxx_amd64.exe) 顯示 64bit process 的 HWND時, 還是只顯示 32 個 bit 但 Window Proc 在 64 或是 WOW64 下大小就有所不同, 可見 HWND 是個 GDI32 產生的數值, 而 HANDLE 或是 HMODULE 則是個記憶體位址. 以 LoadLibrary 為例 HMODULE 的數值其實是 DLL 載入到 Process 中的基底位址.

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; \ typedef struct name##__ *name \ DECLARE_HANDLE (HWND); DECLARE_HANDLE (HHOOK);