C++ 中的奇怪定义预处理器

发布于 2024-11-29 18:25:31 字数 298 浏览 1 评论 0原文

我遇到过这个

#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##_”这个词之外,一切都很清楚,这是什么意思?

I've come across this

#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; }

and everything is clear except the "c##_" word, what does that mean?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

醉梦枕江山 2024-12-06 18:25:31

它的意思是“粘合”在一起,因此 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;
}

It means to "glue" together, so c and _ get "glued together" to form c_. This glueing happens after argument replacement in the macro. See my example:

#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;
}
白日梦 2024-12-06 18:25:31

它被称为令牌粘贴运算符。示例:

// 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

It is called a token-pasting operator. Example:

// preprocessor_token_pasting.cpp
#include <stdio.h>
#define paster( n ) printf( "token" #n " = %d", token##n )
int token9 = 9;

int main()
{
   paster(9);
}

Output

token9 = 9
阳光①夏 2024-12-06 18:25:31

这是将下划线附加到作为 c 传递的名称的串联。所以当你使用

DsHook(a,b,Something)

该部分时就会变成

if (!Something_) 

That's concatenation that appends an underscore to the name passed as c. So when you use

DsHook(a,b,Something)

that part turns into

if (!Something_) 
温柔嚣张 2024-12-06 18:25:31

在预处理器之后,您的宏将扩展为:

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 值连接起来

After the preprocessor, your macro will be expanded as:

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; }

The ## directive concatenates the value of c which you pass as a macro parameter to _

哽咽笑 2024-12-06 18:25:31

简单的一个:

#define Check(a) if(c##x == 0) { }

在调用站点:

int varx; // Note the x
Check(var);

将扩展为:

if(varx == 0) { }

Simple one:

#define Check(a) if(c##x == 0) { }

At call site:

int varx; // Note the x
Check(var);

Would expand as:

if(varx == 0) { }
日暮斜阳 2024-12-06 18:25:31

它称为 Token Concatenation,用于在预处理期间连接 token
例如,以下代码将打印出 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

It is called Token Concatenation and it is used to concatenate tokens during the preprocessing
For example the following code will print out the values of the values of 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;
}

Output:

c=3 c_ = 0 and c_spam = 4
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文