C - 没有函数指针的动态函数调用

mat*_*atg 3 c pointers function dynamic call

我想动态地调用C函数(例如,形成stdlib,math ...).这意味着我的C程序只知道指向随机函数(例如printf)及其签名(编码为char数组:char *,...)的指针.

我的目标是一个reflectCall函数,它获取一个指向函数(&printf)的签名,一个签名(以某种方式编码在a中char[]),参数作为一个long[](long不是实际的数据类型,一个long值也可以表示一个double值,指针, ...).

因此,我的反射函数的签名如下所示:

long reflectCall(void *funcPointer, char[] types, long[] args)
Run Code Online (Sandbox Code Playgroud)

该函数应该对函数进行实际调用,*funcPointer最后返回其结果.

结果,我无法创建指针指针; 比如这个:

int (*functionPtr)(int,int);
Run Code Online (Sandbox Code Playgroud)

任何人都可以给我一个提示如何解决这个问题或建议任何参考实现?

小智 7

它可以在纯C中完成,但它不是那么简单而且不那么快:

  1. 为要调用的所有函数创建包装函数,例如:

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 指向包装函数的指针:

    typedef int (*TWrapper)(const char*,long*,long*);
    
    Run Code Online (Sandbox Code Playgroud)
  3. 为包装函数创建表结构:

    struct STableItem{
        const char *strName;
        TWrapper pFunc;
    };
    
    Run Code Online (Sandbox Code Playgroud)
  4. 创建一个表:

    STableItem table[] = {
        {"printf", &WrapPrintf},
        {"foo", &WrapFoo},
        {NULL, NULL}
    };
    
    Run Code Online (Sandbox Code Playgroud)
  5. 创建接口以从表中调用任何函数(按名称搜索函数并调用它):

    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;
    }
    
    Run Code Online (Sandbox Code Playgroud)
  6. 最后拨打电话:

    long args[] = {123,'b'};
    long results[8];            // not nice but just for an example
    
    int res_count = DynamicCall("printf","ic",(long*)args,(long*)results);
    
    Run Code Online (Sandbox Code Playgroud)

注意:使用哈希函数可以更快地进行名称搜索


Chu*_*uck 4

C 不提供执行此操作的工具。您必须使用特定于平台的 ASM 编写函数主体。