有没有办法用va_args参数包装函数?

时间:2012-02-22 11:25:14

标签: c

有一个功能:

void some_function(int id,...);

问题:有没有办法包装这个功能?这意味着得到这样的东西:

void wrapped_some_function(int id,...)
{
   //do smth
   some_function(id,...);
}

5 个答案:

答案 0 :(得分:5)

使用gcc,__builtin_apply_args__builtin_apply,记录here,可以做到。
对于标准C,没有办法(其他答案建议可以使用,但不是100%你要求的)。
但是,如果some_function的变体va_listvprintf变体为printf),则可以使用它。

答案 1 :(得分:4)

因为这也标记为C ++:C ++ 11 ftw。

#include <utility> // forward

template<class... Args>
void wrapped_some_function(int id, Args&&... args)
{
   //do smth
   some_function(id, std::forward<Args>(args)...);
}

答案 2 :(得分:1)

如果你的编译器支持variadic macros,你可以使用它吗?

#define wrapped_some_function(id, ...)    \
    do {                                  \
        /* Do something here... */        \
        some_function(id, __VA_ARGS__);   \
    } while (0)

答案 3 :(得分:0)

我假设您的包装函数在编译时并不“知道”传递的参数的实际数量(及其类型),否则您只需检索它们并调用包装函数。

然后,这只能通过使用内联汇编程序(因此 - 依赖于平台的解决方案)来解决。这还取决于你想要如何包装你的函数,你需要为你的包装器保留堆栈(即你不需要本地函数变量)等。

答案 4 :(得分:0)

在一般情况下,没有办法做到这一点,因为some_function的创建者不应该提供类似的函数vsome_function,它不需要......,而是va_list。具有可变参数列表的函数必须具有其计数器部分,即具有va_list的函数。考虑一对函数(printf,vprintf),(sprintf,vsprintf),(CString :: Format,CString :: FormatV)。