【问题标题】:how to read a C function from STDIN and run that in program?如何从 STDIN 读取 C 函数并在程序中运行它?
【发布时间】:2013-09-30 16:04:40
【问题描述】:

我想编写一个从 stdin 读取的程序:scanf("%s %s", foo, args); 然后运行带有参数的函数 foo(之前在程序中定义):foo(args); 我不知道如何在 C 中执行此操作。我以前可以在 Shell 中轻松做到这一点,但在 C 中似乎很困难

【问题讨论】:

标签: c


【解决方案1】:

对于这个问题没有同时通用跨平台/标准的解决方案。

不依赖非标准扩展的非通用解决方案:将名称和函数指针对存储在数组中,执行搜索,通过指针调用函数。例如:

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);

【讨论】:

    【解决方案2】:

    另一个难以调试、高度脆弱的解决方案是使用调试符号(或映射文件)进行编译、解析它们并动态调用函数。太疯狂了。

    尽管如此,您真的希望程序中的每一个函数都能以这种方式调用吗?包括main?可能不是。那么,确定一组应该以这种方式调用的函数,并构建一个包含函数名称和函数指针的结构数组。当输入时出现函数名称时,扫描该函数的数组,找到函数指针并调用。如果它们有不同的原型,则添加另一个成员来描述函数期望的参数类型。 (编辑:上面的答案建议相同并提供详细信息)

    【讨论】:

    • 天啊,你的建议真是太疯狂了!太疯狂了,我必须为了好玩而实现它! :D
    • 调试器做到了。只是在说'。 :))) MAP 文件可能更容易解析,并且它具有全局函数的起始地址 - 理论上所有你需要的。要确定代码段在进程地址空间中的偏移量,首先在 MAP 文件中查找当前正在执行的函数。如需加分,请随意从 C++ 名称装饰中推断出原型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-03-27
    • 1970-01-01
    • 1970-01-01
    • 2016-11-28
    • 2012-03-08
    • 1970-01-01
    相关资源
    最近更新 更多