I would like to call C functions (eg form the stdlib, math ...) dynamically. This means that my C program only knows the pointer to a random function (eg 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; eg 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.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.