首页 > 解决方案 > 我可以使用宏自动构建参数列表吗?

问题描述

我一直在写一个小挂钩库,它使用 MS Detours 并且可以在任何进程中附加到任何 MS API 并记录它在做什么。我在我的库中尝试做的一件事是从挂钩中删除所有样板,以便可以非常简单地编写每个挂钩。

我已经把它归结为挂钩 CreateFile 函数并将其第一个参数打印到调试器所需的全部内容:

Hooker hooker;

Hook(hooker, dllnames::Kernel32, apis::T_CreateFileW, CreateFileW, [](auto lpFilename, auto ...rest) -> auto
{
    APILOG(L"%s", lpFilename);
    return TruePtr(lpFilename, rest...);
});

唯一需要的样板是函数指针定义apis::T_CreateFileW。然而,它在很多情况下都让我感到震惊,我甚至可以走得更远。我想知道是否可以使用宏将上述内容编写为:

APILOG(hooker, dllnames::Kernel32, CreateFileW, L"%s", lpFilename);

这意味着几乎可以编写一个 printf 来让我记录任何 API 正在做什么,只要它的参数可以用格式字符串合理地捕获。

但这可能作为宏吗?我想一些问题是:

  1. 我必须将宏的 ... 扩展到两者auto param1, auto param2以及param1, param2.
  2. 无论我是否想要它们,我都必须在我的格式字符串中至少指定并打印真实 API 的前 N ​​个参数,因为只有在那时我才能通过rest...
  3. 如果我想打印所有参数,我将无法通过rest...

有可能我已经尽可能地简化了这个,我只是想看看是否有任何接近它的可能。

标签: c++macros

解决方案


如果不使用多个宏并至少重复一次参数名称,我认为这是不可能的;你可以使用括号传递一个多参数“包”,但你不能对每个参数做一些事情,比如添加auto前缀。

相反,我会考虑使用预处理器以外的其他东西的更高级的代码生成技术。想到了m4 。甚至可以使用一个简单的 shell 脚本。


推荐阅读