Storing variable arguments for future use in C?

Discussion in 'C Programming' started by prasanthag@gmail.com, May 29, 2006.

  1. Guest

    Hi,
    I am a newbie to this group. I have a problem in handling the variable

    arguments passed to a function. My requirement is like this.

    I have 2 functions say,


    void funcX(int i, int j);
    void funcY(int i, int j,char *name);


    Now I want to register this function some how and store the variable
    arguments ( and store defualt values) for future use


    RegisterFunc(funcX,10,20);
    RegisterFunc(funcY,50,60,"MyName");


    ( Here I want to know how I can register and store the variable
    arguments and function pointers, so that it can be used at a later
    point to invoke the same)


    Now at a later point I want to evoke these store functions in a
    sequential order.


    CallFuncs()
    {
    //Invoke funcX with values registered here;
    //Invoke funcY with values registered here;



    }


    I was trying to use va_args with C and somehow i was not able to be
    successful. If anybody have a better suggestion/design on how to do it,
    , May 29, 2006
    #1
    1. Advertising

  2. Richard Bos Guest

    wrote:

    > I have 2 functions say,
    >
    > void funcX(int i, int j);
    > void funcY(int i, int j,char *name);
    >
    > Now I want to register this function some how and store the variable
    > arguments ( and store defualt values) for future use
    >
    > RegisterFunc(funcX,10,20);
    > RegisterFunc(funcY,50,60,"MyName");
    >
    > ( Here I want to know how I can register and store the variable
    > arguments and function pointers, so that it can be used at a later
    > point to invoke the same)


    IOW, you want closures, or something similar to them.

    That isn't easily possible in C. You'd have to write the whole
    infrastructure yourself. funcX and funcY would probably have to be
    rewritten, possibly so they take a va_list instead of their present
    arguments; or your calling function would have to know the prototypes of
    all functions it could ever call, and involve a massive switch. Either
    way, it's ugly.

    Richard
    Richard Bos, May 29, 2006
    #2
    1. Advertising

  3. On 2006-05-29, <> wrote:
    > Hi,
    > I am a newbie to this group. I have a problem in handling the variable
    >
    > arguments passed to a function. My requirement is like this.
    >
    > I have 2 functions say,
    >
    >
    > void funcX(int i, int j);
    > void funcY(int i, int j,char *name);
    >
    >
    > Now I want to register this function some how and store the variable
    > arguments ( and store defualt values) for future use
    >
    >
    > RegisterFunc(funcX,10,20);
    > RegisterFunc(funcY,50,60,"MyName");
    >


    Perhaps in a struct of unions? That would be terribly ugly.

    If all of your functions are like that, you could simple store a
    struct of int, int, char[].

    What I would do for maximum portability is:
    struct function_args
    {
    void *arg[MAX_ARGS];
    int type[MAX_ARGS];
    int num_args;
    };

    Where type would be one of various #defines, such as TP_CHAR
    Obviously, there are an infinite number of types (theoretically),
    so you would need to draw the line at, say, triple indirection.

    So, char ***n would not work as an argument in this library.

    >
    > ( Here I want to know how I can register and store the variable
    > arguments and function pointers, so that it can be used at a later
    > point to invoke the same)
    >
    >
    > Now at a later point I want to evoke these store functions in a
    > sequential order.
    >

    Okay. You would need an array of casting functions, similar to this:
    char *cast_to_char(void *arg)
    {
    char *p = arg;
    return p;
    }

    Each of those would be in an array, and each argument could be accessed
    in its appropriate type like so:

    *(convert[func.type[n]](func.arg[n]));

    So, a three-argument function would be invoked within CallFuncs() like so:

    three_arg_func (*convert [func.type [0]] (func.arg[0]),
    *convert [func.type [1]] (func.arg[1]),
    *convert [func.type [2]] (func.arg[2]));

    Generalizing that to an arbitrary number of arguments will be tricky. I'll
    try to think of a way during school today.

    > I was trying to use va_args with C and somehow i was not able to be
    > successful. If anybody have a better suggestion/design on how to do it,
    >

    Perhaps va_args would be the way to go...

    --
    Andrew Poelstra < http://www.wpsoftware.net/blog >
    To email me, use "apoelstra" at the above address.
    It's just like stealing teeth from a baby.
    Andrew Poelstra, May 29, 2006
    #3
  4. Guest

    wrote:
    > Hi,
    > I am a newbie to this group. I have a problem in handling the variable
    >
    > arguments passed to a function. My requirement is like this.
    >
    > I have 2 functions say,
    >
    >
    > void funcX(int i, int j);
    > void funcY(int i, int j,char *name);
    >
    >
    > Now I want to register this function some how and store the variable
    > arguments ( and store defualt values) for future use
    >
    >
    > RegisterFunc(funcX,10,20);
    > RegisterFunc(funcY,50,60,"MyName");
    >
    > ( Here I want to know how I can register and store the variable
    > arguments and function pointers, so that it can be used at a later
    > point to invoke the same)
    >
    >
    > Now at a later point I want to evoke these store functions in a
    > sequential order.
    >
    >
    > CallFuncs()
    > {
    > //Invoke funcX with values registered here;
    > //Invoke funcY with values registered here;
    >
    >
    >
    > }
    >
    >
    > I was trying to use va_args with C and somehow i was not able to be
    > successful. If anybody have a better suggestion/design on how to do it,


    I really don't think you can do this using varags functions.
    Instead why not something like this:

    /* generic implementation */

    /*
    * Does not support unregistering as that's
    * a bit harder: We need to make sure nothing
    * gets deleted in our list while we're walking
    * it in call_funcs.
    */

    #include <stdlib.h>

    struct func{
    struct func *next;
    void (*f)(void *data);
    void *data;
    };

    static struct func *first;

    int register_func(void (*f)(void *data), void *data){
    struct func *func;
    func = malloc(sizeof *func);

    if(func == NULL){
    return 0;
    }

    /*
    * Initialize: notice that we don't copy data
    * and leave it as responsability of the caller
    * to hand us data that persists until the last
    * call to call_funcs
    */

    func->f=f;
    func->data=data;

    /*
    * Prepend to the list: functions will be
    * called in reverse order from registration
    */

    func->next=first;
    first=func;

    return 1;
    }

    void call_funcs(void){
    struct func *func;
    for(func = first; func != NULL; func = func->next) {
    func->f(func->data);
    }
    }

    /* interface header */

    int register_func(void (*f)(void *data), void *data);
    void call_funcs(void);

    /* Now use this in our program */

    /* missing #include "func.h" to post a single file to clc */

    #include <stdio.h>

    struct argX{
    int a;
    int b;
    };

    struct argY{
    int a;
    int b;
    char *name;
    };

    void funcX(void *data){
    struct argX *X=data;

    printf("funcX with a=%d, b=%d\n",X->a,X->b);
    }

    void funcY(void *data){
    struct argY *Y=data;

    printf("funcY with a=%d, b=%d, name=%s\n",Y->a,Y->b,Y->name);
    }

    int main (void) {

    struct argX X1={1,2};
    struct argX X2={3,4};
    struct argY Y ={5,6,"hello"};

    register_func(funcX,&X1);
    register_func(funcY,&Y);
    register_func(funcX,&X2);

    call_funcs();

    return 0;
    }

    Tobias
    , May 30, 2006
    #4
    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. matevz bradac

    storing variable arguments for future use

    matevz bradac, Apr 15, 2004, in forum: C Programming
    Replies:
    6
    Views:
    343
    matevz bradac
    Apr 17, 2004
  2. Replies:
    2
    Views:
    1,264
    Rolf Magnus
    May 29, 2006
  3. Replies:
    3
    Views:
    821
  4. Navaneeth
    Replies:
    4
    Views:
    550
    Kenny McCormack
    Nov 20, 2010
  5. Abu Yahya
    Replies:
    18
    Views:
    533
    Harry Tuttle
    Jun 10, 2011
Loading...

Share This Page