【问题标题】:C - dynamic function call without a function pointerC - 没有函数指针的动态函数调用
【发布时间】:2013-02-28 16:30:13
【问题描述】:

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

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

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

long reflectCall(void *funcPointer, char[] types, long[] args)

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

因此,我可以创建指针指针;例如喜欢这个:

int (*functionPtr)(int,int);

谁能给我一个提示如何解决这个问题或建议任何参考实现?

【问题讨论】:

  • 平台无关的方式基本上没有办法做到这一点。
  • 抱歉,您不能将可变参数传递给可移植的可变参数函数。 C 只是不支持必要的反射。

标签: c function pointers dynamic call


【解决方案1】:

在纯 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;
    }
    
  2. 指向包装函数的指针:

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

    struct STableItem{
        const char *strName;
        TWrapper pFunc;
    };
    
  4. 创建表:

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

注意:使用散列函数更快地搜索名称

【讨论】:

  • 您能否详细说明一下散列函数以便更快地进行名称搜索?谢谢。
【解决方案2】:

我会建议你看看 libffi,它是否符合你的需求......

http://sourceware.org/libffi/
http://en.wikipedia.org/wiki/Libffi

【讨论】:

    【解决方案3】:

    正如其他地方所解释的,没有办法真正动态地做到这一点。但是,如果您希望使用指针构建函数表,并使用某种字符串或索引来描述您想要做什么,那么这肯定是可能的,以一种可移植的方式。作为各种解析和其他“基于命令的运行代码等”的解决方案,这一点也不罕见。

    但它确实要求您使用某种函数指针[或在某个时间点将您的void * 转换为一个]。没有其他(甚至几乎)可移植的方式在 C 中动态调用函数。

    【讨论】:

      【解决方案4】:

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

      【讨论】:

      • 我可以用 C++ 做这种反射吗? (我还是想调用C函数)
      猜你喜欢
      • 2020-06-28
      • 2012-05-05
      • 1970-01-01
      • 2013-12-23
      • 2012-04-16
      • 1970-01-01
      • 1970-01-01
      • 2014-10-06
      • 1970-01-01
      相关资源
      最近更新 更多