I would like to call C functions (e.g. form the stdlib, math ...) dynamically. This means that my C program only knows the pointer to a random function (e.g. printf
) and its signature (coded as a char array: char *
, ...).
My goal is a reflectCall-function that gets a pointer to a function (&printf
), a signature (somehow coded in a char[]
), and the parameters as a long[]
(long
is not the actual datatype, one long value can also represent a double value, pointer,...).
The signature of my reflect function therefore looks like this:
long reflectCall(void *funcPointer, char[] types, long[] args)
The function should do the actual call of the function *funcPointer
and finally return its result.
As a result, I can not create a pointer pointer; e.g. like this one:
int (*functionPtr)(int,int);
Can anybody give me a hint how to solve this problem or suggest any reference implementation?
It is possible to do it in pure C but it is not so simple and not so quick:
Create wrapper functions for all functions you want to call, such as:
int WrapPrintf(const char* types,long* args,long* results)
{
// Function specific code, in this case you can call printf for each parameter
while(*types)
{
switch(*types){
case 'i':
printf("%d",(int)*args);
break;
case 'c':
printf("%c",(char)*args);
break;
// .. and so on
}
++types;
++args;
}
// Return number of filled results
return 0;
}
int WrapFoo(const char* types,long* args,long* results)
{
// ..function specific code..
return 0;
}
Pointer to a wrapper function:
typedef int (*TWrapper)(const char*,long*,long*);
Create a table structure for wrapped functions:
struct STableItem{
const char *strName;
TWrapper pFunc;
};
Create a table:
STableItem table[] = {
{"printf", &WrapPrintf},
{"foo", &WrapFoo},
{NULL, NULL}
};
Create interface to call any function from the table (search function by name and call it):
int DynamicCall(const char *func_name,const char* types,long* args,long* results)
{
int k;
for(k=0;table[k].strName != NULL;++k){
if(strcmp(func_name,table[k].strName) == 0){
return table[k].pFunc(types,args,results);
}
}
return -1;
}
And finally make a call:
long args[] = {123,'b'};
long results[8]; // not nice but just for an example
int res_count = DynamicCall("printf","ic",(long*)args,(long*)results);
Note: use a hash function for quicker name search
C does not provide the facilities to do this. You'd have to write the body of the function in platform-specific ASM.
I would to recommend you to look at libffi, whether it fits your needs...
http://sourceware.org/libffi/
http://en.wikipedia.org/wiki/Libffi
As explained elsewhere, there is no way to do this truly dynamically. However, if you wish to build a table of functions using pointers, and use some sort of string or index to describe what you want to do, then that would certainly be possible, in a portable way. This is not at all uncommon as a solution for various parsing and other "run code based on commands, etc".
But it does require that you use a function pointer of some sort [or cast your void *
into one at some point or another]. There is no other (even nearly) portable way of calling a function dynamically in C.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With