D中的变量函数调用

时间:2014-03-12 17:39:07

标签: c++ c d

好的,这就是我需要的东西:

  • 我们说我们有一个字符串变量,例如func有一些值,由用户给出(常量)
  • 我们如何调用名称为func
  • 的值的函数

更新

或许我认为我需要的是非常明显的,但是因为我注意到很多事,所以你在这里:

string func = "myfunc";

我需要call(func)之类的内容,它会调用myfunc。就像PHP call_user_func_array()

一样

有什么想法吗?

我看过 mixins ,但这看起来并不像我需要的那样。


PS 我也在用cc++标记问题,因为鉴于语言之间的相似性,理论上可以使用通用解决方案。< / p>

6 个答案:

答案 0 :(得分:4)

编程语言通常不提供在运行时访问函数名的方法,因为这些名称通常被链接器删除,只留下机器代码。

正如user3286380所建议的那样,解决这个问题的一种方法(可以在所有语言中使用)是创建一个表,该表交叉引用函数名和指向各自函数的指针。然后,您的程序可以在运行时查找此表。

如果所讨论的语言允许内省(运行时或编译时),您可以枚举模块或程序中的函数,并找到用户输入其名称的函数。在D中,您可以使用模块上的allMembers trait来完成此操作。这将为您提供模块中所有声明的数组;下一步是过滤掉函数,检查函数签名是否匹配,然后生成一个调用相应函数的switch语句。您可以使用CTFE和字符串mixins来实现上述目的。

答案 1 :(得分:1)

创建一个对数组,每对的第一个元素是字符串函数名,第二个元素是指向函数的指针。搜索数组,找到名称后,使用指针调用它。请注意,Python有一个字典类,使您可以将其作为键:值对执行。

答案 2 :(得分:1)

我看到了3种方法:

  • 如果您事先知道可供选择的功能集合,则可以注册string - &gt;的关联表。 functor其中functor记录函数地址和签名,例如C ++中的std::function

  • 否则,更复杂的解决方案是检查自己的可执行文件的调试符号并从中构建表。您也可以使用预处理器(如Qt的MOC)来构建此表,或者在D的情况下使用内置的编译时反身性。

  • 如果您真的需要灵活性,请使用解释器而不是编译器。 Cling是一个很好的基于LLVM的C ++解释器,具有即时编译功能。

答案 3 :(得分:1)

我以前唯一能做到这一点的方法就是将可执行文件中的函数链接到一个字符串&#34; name&#34;那个功能,然后做一个比较。

我以为我会在C中使用一个简单的(1函数)示例,我必须假设这也适用于D:

typedef struct {
    char * func_name;
    void (* fptr)();
} myS;

void print(){
    printf("hello world\n");
}

int main()
{ 
    myS Ex;
    char str[100] = "";

    // Obviously you can fill these in a more intelligent manner, use an array, etc
    Ex.func_name = malloc(strlen("print")+1);
    strcpy(Ex.func_name, "print");
    Ex.fptr = print;

    printf("Enter the function name\n");
    scanf("%99s", str);

    // and of course with a number of functions to examine you could use a switch
    if(!strcmp(str, Ex.func_name))
        Ex.fptr();
    else
        printf("Didn't find a function to call\n");

    return 0;
}

答案 4 :(得分:0)

我的方法是使用关联数组。一个例子是:

module main;

import std.stdio;

class Tqfuncs{
private:
    void qwrite(string arg){
        write(arg);
    }
    void delegate(string)[string] pList;//store name & pointer to functions here
public:
    this(){
        pList = [
            "qwrite":&qwrite,//add the qwrite function
        ];
    }
    void call(string name, string arg){
        if (name in pList){
            pList[name](arg);//call the function
        }else{
            throw new Exception("unrecognized function call "~name);
        }
    }
}

void main(string[] args){
    Tqfuncs scrF = new Tqfuncs;
    scrF.call("qwrite","This will be written");
}

我已经使用这种方法创建了一种动态脚本语言,您可以使用源https://github.com/Nafees10/qscript了解更多信息。
但是,使用此方法存在一些限制:

  • 所有功能必须采用某种格式&#34;。就像我使用void functionName(string arg)一样。但有一种解决方法,如果您有兴趣,可以在QScript(我的项目)中查看。

答案 5 :(得分:0)

不 - 你不需要用静态类型的语言!周期。

为什么呢? - 因为编译器不能提前知道保存您要运行的函数名称的变量的值(在运行时更改),所以当它遇到def cvt_xls_to_xlsx(*args, **kw): """Open and convert XLS file to openpyxl.workbook.Workbook object @param args: args for xlrd.open_workbook @param kw: kwargs for xlrd.open_workbook @return: openpyxl.workbook.Workbook You need -> from openpyxl.utils.cell import get_column_letter """ book_xls = xlrd.open_workbook(*args, formatting_info=True, ragged_rows=True, **kw) book_xlsx = Workbook() sheet_names = book_xls.sheet_names() for sheet_index in range(len(sheet_names)): sheet_xls = book_xls.sheet_by_name(sheet_names[sheet_index]) if sheet_index == 0: sheet_xlsx = book_xlsx.active sheet_xlsx.title = sheet_names[sheet_index] else: sheet_xlsx = book_xlsx.create_sheet(title=sheet_names[sheet_index]) for crange in sheet_xls.merged_cells: rlo, rhi, clo, chi = crange sheet_xlsx.merge_cells( start_row=rlo + 1, end_row=rhi, start_column=clo + 1, end_column=chi, ) def _get_xlrd_cell_value(cell): value = cell.value if cell.ctype == xlrd.XL_CELL_DATE: value = datetime.datetime(*xlrd.xldate_as_tuple(value, 0)) return value for row in range(sheet_xls.nrows): sheet_xlsx.append(( _get_xlrd_cell_value(cell) for cell in sheet_xls.row_slice(row, end_colx=sheet_xls.row_len(row)) )) for rowx in range(sheet_xls.nrows): if sheet_xls.rowinfo_map[rowx].hidden != 0: print sheet_names[sheet_index], rowx sheet_xlsx.row_dimensions[rowx+1].hidden = True for coly in range(sheet_xls.ncols): if sheet_xls.colinfo_map[coly].hidden != 0: print sheet_names[sheet_index], coly coly_letter = get_column_letter(coly+1) sheet_xlsx.column_dimensions[coly_letter].hidden = True return book_xlsx 它应该生成什么机器代码时?

想象一下你想要的作品:

funcname(myvar)

当funcall()获取返回对象Person(用户定义类型)的函数名称时会发生什么?

此外,当没有名称为string funcname; // here some initialisation code that modifies the funcname int someVal = funcall(funcname); 的函数时会发生什么?运行时错误?没错误?什么?

你想要的是动态语言领域,其中完全忽略了类型安全性(不幸的是大部分都是这样)。

但是......如果您的函数都包含在一个结构中作为示例,那么D提供了一种通过转发(函数调度)执行所需操作的优雅方式。在此处阅读更多相关信息:https://dlang.org/spec/operatoroverloading.html#dispatch