2010-08-07 60 views
7

這是WinNT.h 519線(內部版本號:0091)這行C/C++預處理器是什麼意思?

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

爲什麼我們需要一個指向結構與所謂unused一個奇怪的名字單個int成員?

我們會不會需要使用這樣的一行代碼?

HINSTANCE hInstance = new HINSTANCE__; 

整體聲明具有相同結構的不同數據類型對我沒有意義。這背後有什麼想法?

DECLARE_HANDLE(HRGN); 
DECLARE_HANDLE(HRSRC); 
DECLARE_HANDLE(HSPRITE); 
DECLARE_HANDLE(HLSURF); 
DECLARE_HANDLE(HSTR); 
DECLARE_HANDLE(HTASK); 
DECLARE_HANDLE(HWINSTA); 
DECLARE_HANDLE(HKL); 

回答

1

而且我們將永遠需要使用的代碼行像這樣的?
HINSTANCE hInstance = new HINSTANCE__;

您通常使用由Windows系統調用返回的HINSTANCE值;我從來沒有見過這樣的代碼執行線。

10

關鍵是讓不同的手柄具有不同的類型,例如,HINSTANCE不能分配給手柄。如果它們全部被定義爲「void *」,那麼存在編譯器無法檢測到的錯誤類。

+0

所以,它背後的想法是有整數數據類型不會用於除聲明的目的以外的目的? – 2010-08-07 16:26:02

+0

是的,它爲句柄類型提供了類型安全性,所以當您嘗試將HINSTANCE傳遞給需要HANDLE的函數時,即使底層結構相同,您也會得到一個錯誤。 (這個答案只是「是」,但顯然不夠冗長,加了額外的冗長) – janm 2010-08-08 02:25:09

+0

ahhh我明白了爲什麼C現在不允許匿名結構作爲函數的參數;如果它將匿名結構視爲等同於任何具有相同設置的相同結構,那麼會使C不會導致錯誤,從而使此技巧發揮作用。也就是說,我很確定允許它允許更靈活的代碼,但至少有一個原因。它也似乎表明真正的代碼依賴於指針的大小完全是int,否則句柄會中斷,並且很多代碼需要被重寫。 – Dmitry 2017-01-15 02:19:07

0

它們實際上並不指向任何內存;它們僅用於在調用Windows API時引用對象(文件,資源,信號量,窗口)。雖然它們只不過是索引到內核的對象表中,但開發人員卻決定將它作爲一個指向未使用的結構的指針,這會使它們變得「不透明」,並且導致其他類型之間的混淆更少。 DECLARE_HANDLE是一個函數宏,它可以做到這一點 - 爲句柄聲明不透明類型。