可能重复:
C#预处理器在C 中有什么用途
从有趣的谷歌TTS。。。任何人都可以了解这个代码是如何工作的?特别是-"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;
它在代码中展开为-
// redirect 7th member func of IAsyncReader (SyncReadAlligned) to grab mp3 data from output pin of source filter
DsHook(reader,6,SyncReadAlligned);
我想,这不是一种很安全的记忆游戏方式,但作者认为它"不重要":
像hook这样不重要的代码以片段形式折叠,但可以随意使用以您喜欢的方式展开和格式化代码。
第页。S."谷歌的乐趣"本身如果已经被谷歌屏蔽了(如果有人有兴趣测试的话(。
更新:我认为,简短的分析应该是-为了"重定向IAsyncReader(SyncReadAlligned(的第7个成员函数,从源过滤器的输出引脚获取mp3数据",我们将提交页面的某些区域的内存保护从"原来的"更改为PAGE_EXECUTE_READWRITE(允许完全访问(。
关于安全MSDN说-
最好避免使用VirtualProtect更改上的页面保护由GlobalAlloc、HeapAlloc或LocalAlloc分配的内存块,因为多个存储器块可以存在于单个页面上。。。。在保护将要执行的区域时,调用程序负责确保缓存一致性。。。
这是一个预处理器指令,意思是"串联"。CCD_ 1将产生包含参数CCD_ 2的替代值和文字字符CCD_。示例:
#define foo(c) c##_
当使用foo(bar)
调用时,它将扩展到bar_
。
这个符号##
在宏定义中有一个特殊的含义,即连接。这里c##_
将c与下划线连接以形成新的令牌c_
。注意这里的c是一个参数。因此,通过将hereIAm
作为参数传递给宏,扩展后的c##_
0将变为hereIAm_
。