Storing variable arguments for future use in C?

P

prasanthag

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,
 
R

Richard Bos

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
 
A

Andrew Poelstra

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...
 
T

tobiasoed

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top