如何使用可变长度参数包装函数?

时间:2020-03-05 18:46:56  来源:igfitidea点击:

我正在寻找在C / C ++中执行此操作。

我遇到了可变长度参数,但这建议使用libffi使用Python&C解决方案。

现在,如果我想用myprintf包装printf函数

我所做的如下所示:

void myprintf(char* fmt, ...)
{
    va_list args;
    va_start(args,fmt);
    printf(fmt,args);
    va_end(args);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 9;
    int b = 10;
    char v = 'C';
    myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b);
    return 0;
}

但是结果却不如预期!

This is a number: 1244780 and
this is a character: h and
another number: 29953463

我想念哪里了?

解决方案

回答

我们是什么意思纯C / C ++解决方案?

C运行时跨平台支持rest参数(...)。

http://msdn.microsoft.com/zh-CN/library/kb57fad8.aspx

回答

我们在使用C还是C ++?下一个C ++版本C ++ 0x将支持可变参数模板,这些模板提供了该问题的解决方案。

通过巧妙的运算符重载来实现如下语法,可以实现另一种解决方法:

void f(varargs va) {
    BOOST_FOREACH(varargs::iterator i, va)
        cout << *i << " ";
}

f(args = 1, 2, 3, "Hello");

为了使它起作用,必须实现类varargs来覆盖operator =,后者返回一个代理对象,该代理对象又覆盖`operator'。但是,据我所知,在当前的C ++中使这种变型类型安全是不可能的,因为它必须通过类型擦除来工作。

回答

我也不确定你是什么意思

在C ++中,我们使用

#include <cstdarg>
#include <cstdio>

class Foo
{   void Write(const char* pMsg, ...);
};

void Foo::Write( const char* pMsg, ...)
{
    char buffer[4096];
    std::va_list arg;
    va_start(arg, pMsg);
    std::vsnprintf(buffer, 4096, pMsg, arg);
    va_end(arg);
    ...
}

回答

问题是我们不能在va_args中使用'printf'。如果使用变量参数列表,则必须使用vprintf。 vprint,vsprintf,vfprintf等。(Microsoft C运行时中也有"安全"版本,可防止缓冲区溢出等)

示例工作如下:

void myprintf(char* fmt, ...)
{
    va_list args;
    va_start(args,fmt);
    vprintf(fmt,args);
    va_end(args);
}

int _tmain(int argc, _TCHAR* argv[])
{
    int a = 9;
    int b = 10;
    char v = 'C'; 
    myprintf("This is a number: %d and \nthis is a character: %c and \n another number: %d\n",a, v, b);
    return 0;
}