我有一个带有签名的 3rd 方函数:

int secretfoo(int numargs, ...);

我可以直接调用它,但我真正想要的是用我的函数包装它,向它添加一些额外的参数。

假设整数的简单情况:我希望调用 secretfoo(2, 10, 20) 被翻译为:当我看到参数 10 复制它并进行调用时: secretfoo(3, 10, 10, 20) 。我想在包装器中做到这一点:
int foowrapper(int numargs, ...);

这个包装器分析参数并调用 secretfoo 如上所述。

这可以用 va_list/va_arg 等便携地完成吗?还有什么办法吗?

最佳答案

没有直接操作可变参数列表中的参数的可移植方法,因为这些参数如何传递到函数中高度依赖于平台。而且在大多数硬件架构上,绝对没有办法在列表的中间或末尾插入额外的参数。

如果参数数量有实际上限,则可以通过将所有参数提取到 foowrapper 并“手动”构建新参数列表来调用 secretfoo 来完成。
代码看起来像这样:

int foowrapper(int numarg, ...)
{
  va_list args
  int newargs[numarg*2]; /* worst case allocation */
  int numnewargs = 0;

  /* Extract the arguments */
  va_start(numarg, args);
  for (int i=0; i<numarg; i++)
  {
    newargs[numnewargs++] = va_arg(args, int);

    /* duplicate value 10 as you encounter it */
    if (newargs[numnewargs-1] == 10)
    {
      newargs[numnewargs++] = 10;
    }
  }

  /* Forward to the secretfoo function */
  switch (numnewargs)
  {
  case 0: return secretfoo(0);
  case 1: return secretfoo(1, newargs[0]);
  case 2: return secretfoo(2, newargs[0], newargs[1]);
  /* etc... */
  }
}

关于c - 可移植地扩展 va_list,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3968585/

10-13 09:17