通过用户输入的名称调用函数

时间:2011-02-10 07:13:50

标签: objective-c

是否可以在Objective C中按名称调用函数?例如,如果我知道函数的名称(“foo”),有什么办法可以使用该名称获取指向函数的指针并调用它?我偶然发现了一个类似的python here问题,似乎有可能在那里。我想将一个函数的名称作为用户的输入并调用该函数。此函数不必采用任何参数。

1 个答案:

答案 0 :(得分:7)

对于Objective-C方法,您可以使用performSelector…NSInvocation,例如

NSString *methodName = @"doSomething";
[someObj performSelector:NSSelectorFromString(methodName)];

对于动态库中的C函数,您可以使用dlsym(),例如

void *dlhandle = dlopen("libsomething.dylib", RTLD_LOCAL);
void (*function)(void) = dlsym(dlhandle, "doSomething");
if (function) {
    function();
}

对于静态链接的C函数,通常不是。如果尚未从二进制文件中删除相应的符号,则可以使用dlsym(),例如

void (*function)(void) = dlsym(RTLD_SELF, "doSomething");
if (function) {
    function();
}

更新:ThomasW撰写了一条指向a related question, with an answer by dreamlax的评论,其中包含指向the POSIX page about dlsym的链接。在该答案中,dreamlax注意到以下关于将dlsym()返回的值转换为函数指针变量的信息:

  

C标准实际上并没有定义转换为函数指针和从函数指针转换的行为。解释因为原因而有所不同;最常见的是并非所有体系结构都将函数指针实现为数据的简单指针。在某些体系结构中,函数可能驻留在完全不同的内存段中,使用指向void的指针是无法寻址的。

考虑到这一点,上面dlsym()的调用和所需的功能可以更加轻松,如下所示:

void (*function)(void);
*(void **)(&function) = dlsym(dlhandle, "doSomething");
if (function) {
    (*function)();
}