我有签名的第三方功能:
int secretfoo(int numargs, ...);
我可以直接调用它,但我真正想要的是用我的函数包装它,为它添加一些额外的参数。
假设整数的简单情况:我希望将调用secretfoo(2, 10, 20)
翻译为:当我看到参数10复制它并进行调用时:secretfoo(3, 10, 10, 20)
。我想在包装器中做到这一点:
int foowrapper(int numargs, ...);
此包装器分析argumetns并如上所述调用secretfoo
。
这可以通过va_list
/ va_arg
等方式轻松完成吗?还有别的吗?
答案 0 :(得分:3)
没有可移植的方法直接操作变量参数列表中的参数,因为它是高度平台依赖的,如何将这些参数传递给函数。在大多数硬件架构中,绝对没有办法在列表的中间或末尾插入其他参数。
如果参数数量存在实际上限,则可以通过提取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... */
}
}
答案 1 :(得分:2)
我担心它无法轻松完成。 stdarg.h
“定义了四个宏”(最新C standard draft):va_start
,va_end
,va_arg
和va_copy
。这些都不能用于将va_list
转换回可变数量的值,而不是一个接一个。
您的第三方库应该提供了一个函数vsecretfoo(int, va_list)
,就像标准库对这些情况所做的那样(vprintf
等。)。