HELP:self loading parameters on stack before function call
Quote:
>I am interested in creating a generic piece of code that receives a pointer
>to a function and a buffer with its parameters and calls the function .
>The problem is that the functions prototypes needed to be called aren't
>always the same.They can receive different parameters.
> [snip]
>The problem is that I have to load the parameters on the stack before I call
>the function so that when entering the function it will have the parameters
>it expects.This code cannot be hard coded since the function is generic and
>each time fgen can be pointing to a completely different function which
>recieves different parameters.
>In addition this code must not be sytem dependant.It must run on NT
>as well as Unix so I guess asembler code is not a good idea.
I believe you have constrained the problem to the point that it cannot be
solved. In most implementations I have worked with, what you describe could
only be done in assembly.
There is certainly no portable to do this.
You are assuming that arguments are passed on a stack. This is often true, but
all the recent implementations I'm familiar with have calling conventions
designed to pass as many arguments as possible in registers.
The calling conventions used for C functions aren't fixed by the processor or
the operating system. They're chosen by the compiler writer. They can be
different for two different vendors' compilers for the same processor and
operating system. They can be different for different versions of one vendor's
compiler. They can even differ for the same compiler, just because you changed
some compiler options.
Quote:
>Obviously the same goes for when exiting the function
>I will appreciate any help on the subject including a completely different
>perspective and approach to the problem as long as it is generic and does
>what I want.
There are several alternatives, but it hard to know which to recommend without
knowing more about the problem.
Do you have the option of modifying the functions to be called? If so, you
could rewrite them so that they all have the same type. You could pass them
the buffer you described, or a variable argument list, or a structure which has
enough elements of the right types to handle all the arguments to any of the
functions, or a pointer to such a structure. To get the return value, you
could pass a pointer to the place to store the return value, or return a union
of all the desired return types.
The structure might look something like:
struct arg_catchall {
int i1;
int i2;
int i3;
void *vp1;
void *vp2;
double d1;
double d2;
Quote:
}
In the functions themselves, you could #define macros with more meaningful
names for how the members of the structure are used in that function, for
example (assuming struct arg_catchall *args):
#define RECORD_COUNT (args->i1)
#define RECORD_BUFFER_PTR ((struct record *)args->vp1)
You should probably #undef the macros after the closing brace for the function.
I won't go into variable argument lists, because they're standard and you can
read about them elsewhere. Look in your reference materials for information on
"variable argument lists" and the header file <stdarg.h>. There's a good
chance a variable argument list is the best approach.
If you can't change the functions, but you know in advance what all of them
are, and there aren't too many of them (say, less than 50), you could write a
wrapper function to call each of them. All the wrapper functions would have
the same type.
If you know what all the possible function types (combinations of parameter
lists and return values) are, and there aren't too many, you could write a
wrapper function for each type of function to be called, rather than each
individual function. One of the parameters to these wrapper functions would be
pointer to the function-to-be-called. To execute a function call, you need a
(generic) pointer to the function to be called, a function type code, and the
values to be passed to the function-to-be-called. (If using the buffer
approach you described, only the values are needed - the types are encoded in
the function type code). The function type code is used as an index into an
array of pointers to wrapper functions, to select which wrapper function is
called.
Wheh!
Are you SURE you have to do this? Maybe a different structure for the program
is called for. All of these schemes force you to give up some type-checking by
the compiler, or make it hard to see the flow of data through the program.
(Some do both.)
-- Gary Culp, Sr. Software Engineer, Keil Software, Inc.
--