在c中调用运行时的函数

时间:2013-12-30 20:47:42

标签: c function-pointers

如何在运行时调用函数?我想知道如果不使用 if 开关来调用它,我是否可以这样做,

if(arg[1] == something) //Now what I'm looking for
      call_function;

以下是我正在寻找的,使用arg调用函数print?

#include <stdio.h>

void print()
{

    printf("print function called\n");
}

int main(int argc, char *argv[])
{
    argv[1] to call the print function 
}

那么我可以这样称呼它,

 ./a.out print

3 个答案:

答案 0 :(得分:4)

这不是微不足道或自动的。函数名仅存在于语言中,而不存在于执行程序中。您必须自己提供从合适的字符串常量到函数的映射(或者在Posix上使用一些现有的机制,如dlsym)。您可以通过函数指针

来引用该函数
typedef void (void_function)(void);

extern void print(void);
extern void foo(void);
extern void bar(void);

void_function my_little_functions[] = { print, foo, bar };


int main(int argc, char * argv[])
{
    if (strcmp(argv[1], "print") == 0) { my_little_functions[0](); }
    // ...
}

这仅供参考;而不是一系列条件语句,你应该实现一些合适的函数指针值关联查找结构。

(在C ++中,这将是std::unordered_map<std::string, void_function *>。在C中,你必须找到自己的。)

答案 1 :(得分:2)

如果您不是在寻找“纯C”解决方案,那么您可以使用操作系统的API为您进行映射。在POSIX下(编译并运行):

#include <stdio.h>
#include <dlfcn.h>

void foo(void)
{
    printf("foo\n");
}

void bar(void)
{
    printf("bar\n");
}


void baz(void)
{
    printf("baz\n");
}

int main(int argc, char *argv[])
{
    void *hndl = dlopen(NULL, RTLD_LAZY);
    void (*fn)(void) = dlsym(hndl, argv[1]);

    if (fn) {
        fn();
    } else {
        printf("Function %s() not found\n", argv[1]);
    }

    return 0;
}

答案 2 :(得分:0)

嗯,实际上有办法...

在运行时,您可以编写包含函数定义的.c文件,在main中,您可以编写对argv[1]中命名的函数的调用。然后你可以调用一个编译器(gcc-linux或cl-windows或其他)(通过system(command))来生成一个可执行文件。然后你调用那个可执行文件(通过system(command))并完成工作。

什么?我没有说这是一种实用的方式,我只是说它是一种方式。


证明这确实有效:

#include <stdio.h>
#include <stdlib.h>

const char file_includes[] = "#include <stdio.h>\n";
const char file_functions[] = 
  "void print() {\n"
  "    printf(\"print function called\\n\");\n"
  "}\n"
  "void print2() {\n"
  "    printf(\"second print function called\\n\");\n"
  "}\n";

const char file_main_prolog[] = "int main() {\n";
const char file_main_epilog[] = "  return 0;\n}\n";


int main(int argc, char *argv[]) {
  if (argc < 2) {
    printf("invalid program arguments\n");
    return 1;
  }

  FILE *fout = fopen("function_call.c", "w");

  fprintf(fout, "%s", file_includes);
  fprintf(fout, "%s", file_functions);
  fprintf(fout, "%s", file_main_prolog);
  fprintf(fout, "  %s();\n", argv[1]);
  fprintf(fout, "%s", file_main_epilog);

  fclose(fout);

  system("gcc -o function_call function_call.c");
  system("./function_call");

  return 0;
}

这在linux下安装了gcc。您可以使用参数printprint2运行此程序,您将分别获得print function calledsecond print function called