#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
// some other codes
if(condition1)
{
va_list marker;
va_start(maker, fmt);
// Do something.
va_end(marker);
}
if(somecondition)
boo(fmt, /* I want to put the foo's va_arguments here */);
}
在我的项目中有许多代码调用foo函数 我今天做了一个新的宏嘘声。我想在foo函数中调用宏。
我该怎么做?
修改
当然,我们可以解决这个问题来调用一些函数(非宏),如StringCbVPrintf
但是我找到了一种调用宏的方法。
答案 0 :(得分:1)
问题没有得到妥善解释。这个答案没有回答提问者的想法,但确实回答了似乎被问到的问题。意图与现实之间存在差距。
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__) // semi-colon removed!
void foo(PCSTR fmt, ...)
{
// some other codes
// I want to call boo with VarArgs.
if (somecondition)
boo(fmt, arg1, arg2);
if (anothercondition)
boo("%x %y %z", e1, e2, e3);
if (yetanothercondition)
boo("&T99 P37 T22 9%X ZZQ", x1, y2, z3, a4, b9, c7, q99);
}
除了所有的滑稽之外,你可以使用完成工作所需的参数来调用函数或宏。由于你没有指定格式应该格式化的内容,我已经编写了适合自己的格式字符串 - 它们可能不是很有用,但是谁知道。
无论如何,关键是你可以用不同的参数列表调用boo()
宏,这些参数将传递给SomethingToDo()
。
鉴于评论中的澄清,那么:
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
va_list args;
// I want to call boo with VarArgs.
if (somecondition)
{
va_start(args, fmt);
boo(fmt, args);
va_end(args);
}
}
但是,要使其工作,底层函数需要知道如何处理va_list
。这意味着您通常会得到以下代码,其结构类似于以下内容:
void vSomethingToDo(const char *fmt, va_list args)
{
...code using vfprintf() or whatever...
}
void SomethingToDo(const char *fmt, ...)
{
va_list args;
va_start(args, fmt);
vSomethingToDo(fmt, args);
va_end(args);
}
#define vboo(fmt, args) vSomethingToDo(fmt, args)
#define boo(fmt, ...) SomethingToDo(fmt, __VA_ARGS__)
void foo(PCSTR fmt, ...)
{
...other code...
if (somecondition)
{
va_list args;
va_start(args, fmt);
vboo(fmt, args);
va_end(args);
}
}
这是使用变量参数的代码的“标准模式”。您可以在标准C中看到它:printf()
和vprintf()
; snprintf()
和vsnprintf()
; fprintf()
和vfprintf()
;等等。该函数的一个版本在参数列表中有一个省略号;另一个版本以字母'v'为前缀,并用'va_list'代替省略号。省略号代码标准化为四行或五行 - 如图所示或多或少;它使用va_start创建并初始化va_list,调用v-function,并在执行va_end后返回结果。