我遇到过这个
#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c##_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
一切都很清楚,除了“c##_”这个词,这是什么意思?
我遇到过这个
#define DsHook(a,b,c) if (!c##_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c##_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c##_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
一切都很清楚,除了“c##_”这个词,这是什么意思?
它的意思是“粘合”在一起,所以c
和_
得到“粘合在一起”形成c_
。这种粘合发生在宏中的参数替换之后。看我的例子:
#define glue(a,b) a##_##b
const char *hello_world = "Hello, World!";
int main(int arg, char *argv[]) {
printf("%s\n", glue(hello,world)); // prints Hello, World!
return 0;
}
它被称为标记粘贴操作符。例子:
// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;
int main()
{
paster(9);
}
输出
token9 = 9
这是将下划线附加到作为传递的名称的连接c
。所以当你使用
DsHook(a,b,Something)
那部分变成
if (!Something_)
在预处理器之后,您的宏将扩展为:
if (!c_) { INT_PTR* p=b+*(INT_PTR**)a; VirtualProtect(&c_,4,PAGE_EXECUTE_READWRITE,&no); *(INT_PTR*)&c_=*p; VirtualProtect(p,4,PAGE_EXECUTE_READWRITE,&no); *p=(INT_PTR)c; }
## 指令将您作为宏参数传递给 _ 的 c 的值连接起来
简单一:
#define Check(a) if(c##x == 0) { }
在呼叫现场:
int varx; // Note the x
Check(var);
将扩展为:
if(varx == 0) { }
它被称为令牌连接,用于在预处理期间连接令牌例如以下代码将打印出 c、c_、c_spam 的值的值:
#include<stdio.h>
#define DsHook(a,b,c) if (!c##_) \
{printf("c=%d c_ = %d and c_spam = %d\n",\
c, c##_,c##_spam);}
int main(){
int a,b,c=3;
int c_ = 0, c_spam = 4;
DsHook(a,b,c);
return 0;
}
输出:
c=3 c_ = 0 and c_spam = 4