2013-03-12 89 views
1

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

我的目标是reflectCall功能是获取一个指向函数(&printf),签名(在char[]莫名其妙编码),参数为long[]long是不实际的数据类型,一个长值能也代表一个double值,指针,...)。因此

我反映函数的签名是这样的:

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

功能应该做的功能*funcPointer的实际调用,最后返回其结果。

因此,我可以不是创建一个指针指针;例如像这样:

int (*functionPtr)(int,int); 

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

+0

目前基本上没有办法在一个独立于平台的方式来做到这一点。 – 2013-03-12 22:25:40

+0

对不起,你不能将可变参数传递给可变参数函数。 C只是不支持必要的反思。 – nneonneo 2013-03-12 22:25:48

回答

4

C不提供设施来做到这一点。您必须在平台特定的ASM中编写函数的主体。

+0

可能感兴趣:[libffi](http://sourceware.org/libffi/)。 – duskwuff 2013-03-12 22:28:34

+0

我可以用C++做这种反射吗? (我还想调用C函数) – matg 2013-03-12 22:28:48

+0

@matg:Nope .... – 2013-03-12 22:29:04

2

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

但它确实需要你使用某种类型的函数指针[或者在某个点或另一个点将你的void *转换为一个]。在C中没有其他(甚至几乎)便携式的函数调用方式。

5

这是可能做到这一点在纯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. 用于包裹功能创建的表结构:由名称

    STableItem table[] = { 
        {"printf", &WrapPrintf}, 
        {"foo", &WrapFoo}, 
        {NULL, NULL} 
    }; 
    
  4. 创建界面从表中调用任何功能(搜索功能:

    struct STableItem{ 
        const char *strName; 
        TWrapper pFunc; 
    }; 
    
  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); 
    

注:使用哈希函数更快名称搜索

+0

您能否详细介绍哈希函数,以便更快地进行名称搜索?谢谢。 – Unheilig 2015-05-01 06:33:08