DECLARE_HANDLE 宏,#,## 预处理指令
在WINNT.H中有这样一段代码:
#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #define sabc(val) #val #define glue(a,b) a##b #define MY_DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name struct HTYPE2__ { int unused;}; typedef struct HTYPE2__ * HTYPE2; MY_DECLARE_HANDLE(HTYPE); void CTestGetModuleHandleDlg::OnBtnSendmsg() { //MessageBox(sabc(中国)); //相当于 MessageBox("中国"); /* int c=20,ab=0; glue(a,b) = ++c; //相当于 ab = ++c; CString str; str.Format("%d",ab); MessageBox(str); */ HTYPE__ type; type.unused = 10; HTYPE pType = &type; CString str; HTYPE2 pT = pType; //error C2440: 'initializing' : cannot convert from 'struct HTYPE2__ *' to 'struct HTYPE__ *' str.Format( "%d,%d" ,type.unused,pType->unused); MessageBox(str); } |
Function macro definitions accept two special operators (# and ##) in the replacement sequence:
If the operator # is used before a parameter is used in the replacement sequence, that parameter is replaced by a string literal (as if it were enclosed between double quotes)
|
|
This would be translated into:
|
|
The operator ## concatenates two arguments leaving no blank spaces between them:
|
|
This would also be translated into:
|
|
现在明白了,之所以定义这个宏去声明 结构体与结构体指针,就是为了让句柄之间转化赋值时能在编绎时检测到不匹配的赋值。
从使用者的角度上看,也非常简练。不得不佩服微软的人,确实是个好点子。
【推荐】还在用 ECharts 开发大屏?试试这款永久免费的开源 BI 工具!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步