Calling variadic funcs

Discussion in 'C++' started by keith@bytebrothers.co.uk, Jun 20, 2007.

  1. Guest

    Someone please help me out here - I'm having a 'bad brain' day.

    I have a number of C logging functions, prototyped as, say:

    extern "C" {
    mylog1(char *arg1, char *arg2, char *arg3);
    mylog2(char *arg1, char *arg2, ...);
    mylog3(char *arg1, ...);
    }

    What I want to do is throw a C++ wrapper around them. The first case
    above is pretty trivial:

    MYLOG::eek:ne(char *a1, char *a2, char *a3)
    { mylog1(a1, a2, a3); }

    For the life of me I can't see how I go about passing the variadic
    args for the other two cases!
     
    , Jun 20, 2007
    #1
    1. Advertising

  2. <> wrote in message
    news:...
    :
    : Someone please help me out here - I'm having a 'bad brain' day.
    :
    : I have a number of C logging functions, prototyped as, say:
    :
    : extern "C" {
    : mylog1(char *arg1, char *arg2, char *arg3);
    : mylog2(char *arg1, char *arg2, ...);
    : mylog3(char *arg1, ...);
    : }
    :
    : What I want to do is throw a C++ wrapper around them. The first case
    : above is pretty trivial:
    :
    : MYLOG::eek:ne(char *a1, char *a2, char *a3)
    : { mylog1(a1, a2, a3); }
    :
    : For the life of me I can't see how I go about passing the variadic
    : args for the other two cases!

    The variadic functions are called in the exact same way,
    provided that the function's implementation expects the
    corresponding number of parameters, and of the correct type:

    extern "C" {
    void mylog1(char *arg1, char *arg2, char *arg3);
    void mylog2(char *arg1, char *arg2, ...);
    void mylog3(char *arg1, ...);
    }

    void one(char *a1, char *a2, char *a3) { mylog1(a1, a2, a3); }
    void two(char *a1, char *a2, char *a3) { mylog2(a1, a2, a3); }
    void thr(char *a1, char *a2, char *a3) { mylog3(a1, a2, a3); }



    -Ivan
    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
    Brainbench MVP for C++ <> http://www.brainbench.com
     
    Ivan Vecerina, Jun 20, 2007
    #2
    1. Advertising

  3. On 2007-06-20 13:15, wrote:
    > Someone please help me out here - I'm having a 'bad brain' day.
    >
    > I have a number of C logging functions, prototyped as, say:
    >
    > extern "C" {
    > mylog1(char *arg1, char *arg2, char *arg3);
    > mylog2(char *arg1, char *arg2, ...);
    > mylog3(char *arg1, ...);
    > }
    >
    > What I want to do is throw a C++ wrapper around them. The first case
    > above is pretty trivial:
    >
    > MYLOG::eek:ne(char *a1, char *a2, char *a3)
    > { mylog1(a1, a2, a3); }
    >
    > For the life of me I can't see how I go about passing the variadic
    > args for the other two cases!


    If you have a C99 compliant compiler take a look at the va_* macros in
    stdarg.h. For older compilers look at varargs.h.

    --
    Erik Wikström
     
    =?ISO-8859-1?Q?Erik_Wikstr=F6m?=, Jun 20, 2007
    #3
  4. Guest

    On 20 Jun, 13:38, Erik Wikström <> wrote:
    > On 2007-06-20 13:15, wrote:
    >
    > > For the life of me I can't see how I go about passing the variadic
    > > args for the other two cases!

    >
    > If you have a C99 compliant compiler take a look at the va_* macros in
    > stdarg.h. For older compilers look at varargs.h.


    I spotted those, but they appear to require that you know how many
    arguments are being passed in. I suppose I can count the format
    specifiers in the format string that comes in, and assume that is
    equal to the number of following arguments...
     
    , Jun 20, 2007
    #4
  5. Zeppe Guest

    wrote:
    > On 20 Jun, 13:38, Erik Wikström <> wrote:
    >> On 2007-06-20 13:15, wrote:
    >>
    >>> For the life of me I can't see how I go about passing the variadic
    >>> args for the other two cases!

    >> If you have a C99 compliant compiler take a look at the va_* macros in
    >> stdarg.h. For older compilers look at varargs.h.

    >
    > I spotted those, but they appear to require that you know how many
    > arguments are being passed in. I suppose I can count the format
    > specifiers in the format string that comes in, and assume that is
    > equal to the number of following arguments...
    >

    To be honest, I doubt that you can wrap easily a variable arguments
    function as you want. There is a macro __VA_ARGS__ for the variable
    arguments macro, but I'm not really sure that you can pass a variable
    number of arguments to a function in a compact form with the expressive
    power of the language...

    Regards,

    Zeppe
     
    Zeppe, Jun 20, 2007
    #5
  6. Guest

    On 20 Jun, 14:23, Zeppe <zep_p@.remove.all.this.long.comment.yahoo.it>
    wrote:
    > wrote:
    > > I spotted those, but they appear to require that you know how many
    > > arguments are being passed in. I suppose I can count the format
    > > specifiers in the format string that comes in, and assume that is
    > > equal to the number of following arguments...

    >
    > To be honest, I doubt that you can wrap easily a variable arguments
    > function as you want. There is a macro __VA_ARGS__ for the variable
    > arguments macro, but I'm not really sure that you can pass a variable
    > number of arguments to a function in a compact form with the expressive
    > power of the language...


    Well, I'm pretty sure that this isn't correct by any standard, and the
    chances of it working on a different platform are probably close to
    zero, because I'm relying on "..." being synonymous with a parameter
    of type 'va_list', but having said all that, this works:

    extern "C" {
    void dprintf(enum e_dlog level, char *format, ...);
    }

    #include <stdarg.h>
    void DLOG::log(enum e_dlog level, char *fmt, ...)
    {
    va_list args;
    va_start(args, fmt);
    dprintf(level, fmt, args);
    }
     
    , Jun 20, 2007
    #6
  7. Zeppe Guest

    wrote:

    > Well, I'm pretty sure that this isn't correct by any standard, and the
    > chances of it working on a different platform are probably close to
    > zero, because I'm relying on "..." being synonymous with a parameter
    > of type 'va_list', but having said all that, this works:
    >
    > extern "C" {
    > void dprintf(enum e_dlog level, char *format, ...);
    > }
    >
    > #include <stdarg.h>
    > void DLOG::log(enum e_dlog level, char *fmt, ...)
    > {
    > va_list args;
    > va_start(args, fmt);
    > dprintf(level, fmt, args);
    > }


    Well, I have to admit that the standard is quite cryptic in this:

    If access to the varying arguments is desired, the called function shall
    declare an object (generally referred to as ap in this subclause) having
    type va_list. The object ap may be passed as an argument to another
    function; if that function invokes the va_arg macro with parameter ap,
    the value of ap in the calling function is indeterminate and shall be
    passed to the va_end macro prior to any further reference to ap.

    I can understand that you are allowed to pass ap as an argument, but
    that the function that makes use of the object ap shall invoke the
    va_arg with ap, it shouldn't declare a new va_list (as dprintf in your
    case does). I think your code is working just by chance, because it
    happens that the arguments are aligned in the stack in the correct way
    when you call the dprintf function.

    Pay attention to that.

    Regards,

    Zeppe
     
    Zeppe, Jun 20, 2007
    #7
  8. On Wed, 20 Jun 2007 06:36:04 -0700, keith wrote:
    > On 20 Jun, 14:23, Zeppe <zep_p@.remove.all.this.long.comment.yahoo.it>
    > wrote:
    >> wrote:
    >> > I spotted those, but they appear to require that you know how many
    >> > arguments are being passed in. I suppose I can count the format
    >> > specifiers in the format string that comes in, and assume that is
    >> > equal to the number of following arguments...

    >>
    >> To be honest, I doubt that you can wrap easily a variable arguments
    >> function as you want. There is a macro __VA_ARGS__ for the variable
    >> arguments macro, but I'm not really sure that you can pass a variable
    >> number of arguments to a function in a compact form with the expressive
    >> power of the language...

    >
    > Well, I'm pretty sure that this isn't correct by any standard, and the
    > chances of it working on a different platform are probably close to
    > zero, because I'm relying on "..." being synonymous with a parameter of
    > type 'va_list', but having said all that, this works:
    >
    > extern "C" {
    > void dprintf(enum e_dlog level, char *format, ...); }
    >
    > #include <stdarg.h>
    > void DLOG::log(enum e_dlog level, char *fmt, ...) {
    > va_list args;
    > va_start(args, fmt);
    > dprintf(level, fmt, args);
    > }


    For printf and friends there are vprintf and such which will accept a
    va_list argument. Maybe there is a vdprintf wherever dprintf came from.

    You also need a va_end(args); at the end of your function.

    --
    Markus Schoder
     
    Markus Schoder, Jun 20, 2007
    #8
  9. red floyd Guest

    Erik Wikström wrote:
    >
    > If you have a C99 compliant compiler take a look at the va_* macros in
    > stdarg.h. For older compilers look at varargs.h.
    >


    stdarg.h is C90, not just C99.
     
    red floyd, Jun 20, 2007
    #9
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. steffen staehle
    Replies:
    0
    Views:
    499
    steffen staehle
    Sep 7, 2004
  2. Colin Walters
    Replies:
    2
    Views:
    535
    Ben Pfaff
    Feb 13, 2004
  3. Ross A. Finlayson
    Replies:
    19
    Views:
    623
    Keith Thompson
    Mar 10, 2005
  4. Replies:
    2
    Views:
    361
    Dave Thompson
    Feb 27, 2006
  5. Replies:
    5
    Views:
    375
Loading...

Share This Page