是否可以调用C函数,并将其名称作为字符串?

我在其中一个C谜题中看到了这个问题!! 这真的有可能吗?

如果将其名称作为字符串,我如何调用函数? 是否可以使用scanf读取的字符串直接用于调用函数?

我已经想过if(strcmp(str,“string”))然后调用该函数。

但还有其他方法吗?

既然没有提到什么是函数,也没有提到它的参数,我会想象它是这样的:

 typedef void(* foo)();
 struct puzzleFoo {
    char * function_name;
    foo * fn;
 };

使用字符串参数基于结构创建查找表

 struct puzzleFoo * Lookup(const char * function_name);

然后遍历一个数组/列表,查找puzzleFoofunction_nam e并执行名为fn的函数指针。

使用POSIX.1-2001,您应该使用dlopen()和dlsym() 。 在Windows上使用GetModuleHandleEx()和GetProcAddress() 。

以下是从手册中逐字加载数学库中名为“cos”的函数并确定2.0的余弦的示例:

 #include  #include  #include  int main(int argc, char **argv) { void *handle; double (*cosine)(double); char *error; handle = dlopen("libm.so", RTLD_LAZY); if (!handle) { fprintf(stderr, "%s\n", dlerror()); exit(EXIT_FAILURE); } dlerror(); /* Clear any existing error */ /* Writing: cosine = (double (*)(double)) dlsym(handle, "cos"); would seem more natural, but the C99 standard leaves casting from "void *" to a function pointer undefined. The assignment used below is the POSIX.1-2003 (Technical Corrigendum 1) workaround; see the Rationale for the POSIX specification of dlsym(). */ *(void **) (&cosine) = dlsym(handle, "cos"); if ((error = dlerror()) != NULL) { fprintf(stderr, "%s\n", error); exit(EXIT_FAILURE); } printf("%f\n", (*cosine)(2.0)); dlclose(handle); exit(EXIT_SUCCESS); } 

你可能偷偷摸摸:

 if (strcmp (fn, "function1") == 0) function1(); if (strcmp (fn, "function2") == 0) function2(); if (strcmp (fn, "function3") == 0) function3(); 

或者您可以使用dlopendlsym (或等效的),具体取决于您的执行环境,但这些不是标准C,因此可能不是一个选项。

除了令人难以置信的非可移植填充可执行文件或设计可怕的宏(这很可能归结为上面显示的if语句的集合,或某种类型的函数指针数组)之外,这就是我所拥有的所有东西。

如果该函数在共享库中可用,则可以在运行时加载共享库并访问符号表,该表可以转换为函数名和指针。 至于确保函数调用签名是正确的,你是独立的。

VxWorks为其内置shell执行此操作。

是的,有时。

在Linux下,您可以使用dlopen()打开包含所需function的共享库,甚至可以访问当前可执行文件并使用dlsym()定位您的函数

在Windows上,通常分别调用LoadLibrary()GetProcAddress()

如果有问题的库的符号表已被剥离,或者在某些情况下,如果这些方法是静态/私有的,那么您将无法使用此方法访问它们。

另外,不要忘记,如果你的库是用C ++编写的,那么你可能不得不与名称修改争用。 您需要了解编译器使用的修改方法。

它取决于你想要调用的函数。
如果这是来自DLL或其他类型的导出二进制文件的函数 – 当然可以。
有一个普通的API。
如果此函数未导出并且是以可执行文件编译的 – 当然不是,因为func名称等信息会被截断。

我把它写在了我的头顶 – 不能保证它甚至可以编译,但它可能非常接近。 足以接受采访。

 #include  #include  char *program = "#include\ \ void Func1() { printf("hi\n"); }\ void Func2() { printf("hello\n"); }\ void Func3() { printf("hey\n"); }\ main() {\ "; char *program1 = "}\n"; static in ContainsFunction(char *func) { char *match = strstr(func, program); if (!match || match - program < 5) return 0; int len = strlen(func); return strcmp(match-5, program) == 0 && match[len + 1] == '(' && isalnum(func[len-1]); } static void Compile(char *prog) { pid_t pid = fork(); if (pid == 0) { execl("/usr/bin/gcc", "gcc", prog, (char *)0); } else if (pid < 0) { printf("fork fail\n"); } else { pid_t ws = wait(); } } static void Execute(char *prog) { pid_t pid = fork(); if (pid == 0) { execl(prog, prog, (char *)0); } else if (pid < 0) { printf("fork fail\n"); } else { pid_t ws = wait(); } } static void CallFunction(char *funcname) { FILE *fp = fopen("foo.c", "w"); fputs(program, fp); fprintf(fp, "\t%s();\n", funcname); fputs(fp, program1); fclose(fp); Compile("foo.c"); Execute("a.out"); } int main() { char funcname[8192]; /* too small, fail */ puts("Who ya gonna call?"); gets(funcname); if (ContainsFunction(funcname)) { CallFunction(funcname)); } else { printf("fail - no function %s\n", funcname); } }