470,862 Members | 1,708 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 470,862 developers. It's quick & easy.

Storing variable arguments for future use in C?

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 '06 #1
3 2292
pr********@gmail.com 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
May 29 '06 #2
On 2006-05-29, pr********@gmail.com <pr********@gmail.com> 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.
May 29 '06 #3
pr********@gmail.com 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 '06 #4

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by vegetax | last post: by
2 posts views Thread by Ryan Wilcox | last post: by
4 posts views Thread by matevz bradac | last post: by
14 posts views Thread by Luiz Antonio Gomes Pican?o | last post: by
5 posts views Thread by Sathyaish | last post: by
2 posts views Thread by prasanthag | last post: by
1 post views Thread by RS24 | last post: by
4 posts views Thread by Neo | last post: by
6 posts views Thread by CptDondo | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.