来自Fun with Google 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);
我猜,这不是一种非常安全的玩记忆方式,但作者评价为“不重要”:
像钩子这样的重要代码以代码段形式折叠,但随意 以您喜欢的方式展开和格式化代码。
P.S。如果谷歌已经阻止了“谷歌的乐趣”本身(如果有人有兴趣测试)。
更新:我认为,简短的分析是 - 要“重定向IAsyncReader的第7个成员函数(SyncReadAlligned)以从源过滤器的输出引脚获取mp3数据”,我们将已提交页面的某些区域的内存保护从“它是什么”更改为PAGE_EXECUTE_READWRITE(允许完全访问)。
关于安全MSDN说 -
最好避免使用VirtualProtect更改页面保护 由GlobalAlloc,HeapAlloc或LocalAlloc分配的内存块, 因为单个页面上可以存在多个内存块。 ... 保护可执行区域时,调用程序 承担确保缓存一致性的责任......
答案 0 :(得分:5)
这是一个预处理器指令,意思是“连接”。 c##_
将生成一个包含参数c
和文字字符_
的替代值的标记。例如:
#define foo(c) c##_
使用foo(bar)
调用时,会扩展为bar_
。
答案 1 :(得分:2)
这种符号##
在宏定义中具有特殊含义,即连接。这里c##_
将c与下划线连接起来形成一个新的令牌c_
。注意这里c是一个参数。因此,将hereIAm
作为参数传递给宏后,展开后c##_
将成为hereIAm_
。