leaf wrote:
Hi,
How to call function at runtime,
based on a struct that contains the information for the function call:
struct func_to_call {
int function_id; // function id to call
unsigned int nparams; // number of parameters
unsigned long* parameter; // the parameter(s) to pass
}
This is not portable in portable C++. The number of functions passed in
a function call are determined at compile time, and comiple time is
something that occurs prior to execution time. C++ does not define any
way of dynamic compiling and loading.
What you can do is pre-compile some cooked function calls, and have a
big switch statement which selects one of these calls based on the
parameters.
For instance, suppose all the parameters are restricted to type int,
and the only variation is in the parameter number. Then, given a
pointer to the function ptr, and an array of integer arguments
int_arg[], you can do something like:
switch (number_of_arguments) {
case 0:
{
void (*func)() = (void (*)()) ptr;
func();
}
break;
case 1:
{
void (*func)(int) = (void (*)(int)) ptr;
func(int_arg[0]);
}
break;
case 2:
{
void (*func)(int, int) = (void (*)(int, int)) ptr;
func(int_arg[0], int_arg[1]);
}
break;
/* ... other cases ... */
}
This kind of "glue" code can quickly explode in size, since you have to
write the source code for every kind of binary interface you want to
call, include it in the body of the program, and have a way to route
control to it.
There is a library (GNU GPL'ed though!) for constructing C function
argument lists dynamically and calling functions. The name of this
library is "libavcall" and it was originally written by Bill Triggs.
This library defines a set of macros which, loosely speaking, function
as "opposites" to the standard <stdarg.h> macros va_list, va_arg. That
is why the letter "AV" are used to name the library: VA backwards.
When you construct a list with a specific return type and arguments, it
is automagically copmatible with a function which has that signature,
so then all that is needed is a pointer to that function and you can
call it.
The avcall library is not written portably. It contains a lot of
compiler and platform specific code. It has to understand the calling
conventions of the architecture and operating system platform, so that
given any dynamically constructed av_list, it constructs the right kind
of function calling linkage and performs the right kind of cleanup
afterward.