我想编写一个从stdin读取的程序:scanf("%s %s", foo, args);
然后使用参数运行函数foo(之前在程序中定义):foo(args);
我不知道如何在C中执行此操作。我之前可以很容易地在Shell中做到这一点,但在C
答案 0 :(得分:6)
此问题没有解决方案,同时概括和跨平台/标准。
不依赖于非标准扩展的非通用解决方案:在数组中存储名称和函数指针对,执行搜索,通过指针调用函数。例如:
struct namedfunc {
const char *name;
void (*fptr)(void);
} fvect[3] = {
{ "foo", foo_impl },
{ "bar", bar_impl },
{ "baz", baz_impl }
};
char buf[0x100];
fgets(buf, sizeof buf, stdin);
char *p = strchr(buf, '\n');
if (p != NULL)
*p = 0;
for (size_t i = 0; i < sizeof fvect / sizeof fvect[0]; i++) {
if (strcmp(buf, fvect[i].name) == 0) {
fvect[i].fptr();
break;
}
}
依赖于动态加载的更通用的解决方案:使用dlopen()
API,如下所示:
void *hndl = dlopen(RTLD_SELF, RTLD_LAZY); // try NULL if RTLD_SELF doesn't work
void (*fptr)(void) = dlsym(hndl, buf);
if (fptr != NULL)
fptr();
dlclose(hndl);
答案 1 :(得分:2)
另一个难以调试,高度脆弱的解决方案将涉及使用调试符号(或映射文件)进行编译,解析它们并动态调用该函数。那太疯狂了。
但合理的是,您是否真的希望程序中的每个函数都以这种方式调用?包括main
?可能不是。那么,确定一组应该以这种方式调用的函数,并构建一个包含函数名和函数指针的结构数组。在输入时显示函数名称时,扫描该函数的数组,找到函数指针并调用。如果他们有不同的原型,添加另一个成员来描述函数所期望的参数类型。 (编辑:上面的答案表明相同并提供了详细信息)