views:

64

answers:

4

Hi all,

I have thousands of function wrappers which inside actually perform a similar logic like:

// a, b, ... are variable length parameters of different type

void API_Wrapper(hHandle, a, b, ..)
{
if (hHandle)
   return remote_API(hHandle, a, b, ..);
else
   return API(a, b, ..);
}

I wanna use a macro to reuse the if-else logic so I can simply implement the function like this:

void API_Wrapper(hHandle, a, b, ..)
{
    API_CALL(api_name, hHandle, a, b, ..); // API_CALL is a macro
}

I didn't come up with a good way. (Note: I could solve it via ... and va_args but this extension is not supported by the compiler we currently use)

Anyone ever met the same problem and any idea? Thanks very much!

A: 

define separate API_CALL0, API_CALL1 etc:) You may wanna look into something that will automate the whole API_Wrapper thing, btw

A: 
#define API_CALL(api_name, hHandle, ...) if (hHandle) remote##api_name(hHandle, __VA_ARGS__); else api_name(hHandle, __VA_ARGS__);

void API_Wrapper(int hHandle, int a, double b, char c)
{
            API_CALL(api_name, hHandle, a, b, c);
}

Which becomes

void API_Wrapper(int hHandle, int a, double b, char c)
{
     if (hHandle) remoteapi_name(hHandle, a, b, c); else api_name(hHandle, a, b, c);;
}
Sjoerd
Thanks. The problem is the __VA_ARGS__ is not portable right now and our compiler doesn't support it (msvc7.1, gcc3.4).
Eric
looks like a preprocessor thing
A: 

Using BOOST_PP_SEQ_XXXX you can write your wrapper table in a way similar to this:

WRAP_API(myfunc1, param(int, k) param(double, r) param(char*, s))
                               ^                ^
                               ^blank           ^blank

WRAP_API(myfunc2, param(int, k) )

....

without variadic macros you can use space separated list which is treated as single macro parameter + some preprocessor techics incapsulated in boost pp

+1  A: 

Another trick, without variadic macro's:

#define API_CALL(hHandle, api_name, arguments) if (hHandle) return remote_##api_name arguments; else return api_name arguments;

void API_Wrapper(int hHandle, int a, double b, char c)
{
            API_CALL(hHandle, api_name, (a, b, c));
}

Which becomes:

void API_Wrapper(int hHandle, int a, double b, char c)
{
     if (hHandle) return remote_api_name (a, b, c); else return api_name (a, b, c);;
}
Sjoerd