VA_PASS
VA_PASS
出處
http://www.codeproject.com/KB/tips/va_pass.aspx
http://ramaswamy.r.googlepages.com/ellipsis(...)and__va_args__
內文
1
template<byte count>
struct SVaPassNext{
SVaPassNext<count-1> big;
DWORD dw;
};
template<> struct SVaPassNext<0>{};
//SVaPassNext - is generator of structure of any size at compile time.
class CVaPassNext{
public:
SVaPassNext<50> svapassnext;
CVaPassNext(va_list & args){
try{//to avoid access violation
memcpy(&svapassnext, args, sizeof(svapassnext));
} catch (...) {}
}
};
#define va_pass(valist) CVaPassNext(valist).svapassnext
#if 0 //using:
void MyVA_Function(szFormat, ...){
va_list args;
va_start(args, szFormat);
SomeOtherVA_Function(szFormat, va_pass(args));
va_end(args);
}
#endif
2
#define SENTINEL -32768 // Used to mark the end of Variable Argument List
#define MAX_PARAMS 10
struct va_pass_intlist
{
int list[MAX_PARAMS];
va_pass_intlist(va_list & args)
{
va_list countArgs = args;
byte paramCount = 0;
while ( SENTINEL != va_arg(countArgs, int) )
++paramCount;
ASSERT(paramCount <= MAX_PARAMS);
memcpy(this, args, sizeof(int) * paramCount);
}
};
int average(int first, ...)
{
va_list args, params;
params = va_start(args, first);
va_pass_intlist myparams(params);
int count = 0,
sum = sum(first, myparams);
while( SENTINEL != va_arg(args, int) )
++count;
return sum / count;
}
My Modify and Full test Code
- Portable - test in VC9 , GCC 3.2.2 and GCC 4.2.4
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include <memory.h>
#ifdef _MSC_VER
#define SNPRINTF _snprintf
#else
#define SNPRINTF snprintf
#endif
template<char count>
struct SVaPassNext{
SVaPassNext<count-1> big;
unsigned int dw;
};
template<> struct SVaPassNext<0>{};
class CVaPassNext{
public:
SVaPassNext<16> svapassnext;
CVaPassNext(va_list& args){
try{
memcpy(&svapassnext, args, sizeof(svapassnext));
} catch (...) {}
}
};
template<char count>
class CVaPassNextN{
public:
SVaPassNext<count> svapassnext;
CVaPassNextN(va_list& args){
try{
memcpy(&svapassnext, args, sizeof(svapassnext));
} catch (...) {}
}
};
#define va_pass(x) CVaPassNext(x).svapassnext
//n need defined in compiler time
#define va_pass_n(x,n) CVaPassNextN<n>(x).svapassnext
int myprint1(char* format,...)
{
static char tempstr[512];
va_list list;
va_start(list,format);
SNPRINTF(tempstr, 512, format,va_pass(list));
va_end(list);
printf(tempstr);
return 0;
}
int myprint2(char* format,...)
{
static char tempstr[512];
va_list list;
va_start(list,format);
SNPRINTF(tempstr, 512, format,va_pass_n(list,4));
va_end(list);
printf(tempstr);
return 0;
}
int main(int argc, char* argv[])
{
myprint1("test1 %d, %s, %d\n", 11, "22" , 33);
myprint2("test2 %d, %s, %d\n", 11, "22" , 33);
#ifdef _MSC_VER
system("PAUSE");
#endif
return 0;
}