简体   繁体   中英

C - dynamic function call without a function pointer

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:

  1. 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; } 
  2. Pointer to a wrapper function:

     typedef int (*TWrapper)(const char*,long*,long*); 
  3. Create a table structure for wrapped functions:

     struct STableItem{ const char *strName; TWrapper pFunc; }; 
  4. Create a table:

     STableItem table[] = { {"printf", &WrapPrintf}, {"foo", &WrapFoo}, {NULL, NULL} }; 
  5. 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; } 
  6. 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM