在C中,是否有可能转发可变函数的调用?如,
int my_printf(char *fmt, ...) {
fprintf(stderr, "Calling printf with fmt %s", fmt);
return SOMEHOW_INVOKE_LIBC_PRINTF;
}
在这种情况下,以上述方式转发调用显然不是严格必要的(因为您可以以其他方式记录调用,或使用vfprintf),但我正在处理的代码库要求包装器做一些实际工作,并且没有(也不可能添加)类似于vfprintf的帮助函数。
[更新:根据目前提供的答案,似乎有一些困惑。用另一种方式来表达这个问题:一般来说,你可以在不修改函数定义的情况下包装任意的变进函数吗?
基本上有三种选择。
一种是不传递它而是使用目标函数的变进实现而不传递椭圆。另一种方法是使用可变宏。第三个选择是我所缺少的所有东西。
我通常选择第一种,因为我觉得这真的很容易处理。选项二有一个缺点,因为调用可变宏有一些限制。
下面是一些示例代码:
#include <stdio.h>
#include <stdarg.h>
#define Option_VariadicMacro(f, ...)\
printf("printing using format: %s", f);\
printf(f, __VA_ARGS__)
int Option_ResolveVariadicAndPassOn(const char * f, ... )
{
int r;
va_list args;
printf("printing using format: %s", f);
va_start(args, f);
r = vprintf(f, args);
va_end(args);
return r;
}
void main()
{
const char * f = "%s %s %s\n";
const char * a = "One";
const char * b = "Two";
const char * c = "Three";
printf("---- Normal Print ----\n");
printf(f, a, b, c);
printf("\n");
printf("---- Option_VariadicMacro ----\n");
Option_VariadicMacro(f, a, b, c);
printf("\n");
printf("---- Option_ResolveVariadicAndPassOn ----\n");
Option_ResolveVariadicAndPassOn(f, a, b, c);
printf("\n");
}
如果可以使用c++ 11或更高版本的编译器编译代码,则可以使用可变参数函数模板:
#include <stdio.h>
template<typename... Targs>
int my_printf(const char *fmt, Targs... Fargs) {
fprintf(stderr, "Calling printf with fmt %s", fmt);
return printf(fmt, Fargs...);;
}
int main() {
my_printf("test %d\n", 1);
return 0;
}
Demo
基本上有三种选择。
一种是不传递它而是使用目标函数的变进实现而不传递椭圆。另一种方法是使用可变宏。第三个选择是我所缺少的所有东西。
我通常选择第一种,因为我觉得这真的很容易处理。选项二有一个缺点,因为调用可变宏有一些限制。
下面是一些示例代码:
#include <stdio.h>
#include <stdarg.h>
#define Option_VariadicMacro(f, ...)\
printf("printing using format: %s", f);\
printf(f, __VA_ARGS__)
int Option_ResolveVariadicAndPassOn(const char * f, ... )
{
int r;
va_list args;
printf("printing using format: %s", f);
va_start(args, f);
r = vprintf(f, args);
va_end(args);
return r;
}
void main()
{
const char * f = "%s %s %s\n";
const char * a = "One";
const char * b = "Two";
const char * c = "Three";
printf("---- Normal Print ----\n");
printf(f, a, b, c);
printf("\n");
printf("---- Option_VariadicMacro ----\n");
Option_VariadicMacro(f, a, b, c);
printf("\n");
printf("---- Option_ResolveVariadicAndPassOn ----\n");
Option_ResolveVariadicAndPassOn(f, a, b, c);
printf("\n");
}
C99支持可变参数宏;取决于你的编译器,你可以声明一个宏来做你想做的事情:
#define my_printf(format, ...) \
do { \
fprintf(stderr, "Calling printf with fmt %s\n", format); \
some_other_variadac_function(format, ##__VA_ARGS__); \
} while(0)
不过,一般来说,最好的解决方案是使用您试图包装的函数的va_list形式(如果存在的话)。