如何从name调用c函数,它存储在char *指针中?

时间:2011-06-28 08:49:02

标签: c++ c linux

我想通过名称动态调用函数,例如,假设有以下函数和字符串:

void do_fork()
{
   printf ("Fork called.\n");

}

char *pFunc = "do_fork";

现在我需要do_fork()致电*pFunc。那可能吗?

欢迎使用C / C ++代码,非常感谢!

5 个答案:

答案 0 :(得分:14)

C和C ++都没有足够的反射来开箱即用,所以你必须实现自己的方案。

在C ++中,或多或少的规范方法是使用字符串映射来实现指针。像这样:

typedef void (*func_t)();
typedef std::map<std::string,func_t> func_map_t;

// fill the map
func_map_t func_map;
func_map["do_fork"] = &do_fork;
func_map["frgl"] = &frgl;

// search a function in the map
func_map_t::const_iterator it = func_map.find("do_fork");
if( it == func_map.end() ) throw "You need error handling here!"
(*it->second)();

当然,这仅限于具有完全相同签名的功能。但是,通过使用std::functionstd::bind而不是普通函数指针,可以稍微提升此限制(以包含合理兼容的签名)。

答案 1 :(得分:4)

不完全确定这是否是您正在寻找的内容,但您可以轻松使用dlopendlsym

void *dlsym(void *restrict handle, const char *restrict name);
  

dlsym()函数应该获取   一个符号中定义的符号的地址   通过一个可以访问的对象   dlopen()调用。 handle参数是   调用返回的值   dlopen()(从那以后就没有了   通过调用dlclose()释放,和    name是符号的名称   字符串。

也就是说,它通常不会在C中出现,因此您可能实际上并不需要它。

答案 2 :(得分:1)

确实有可能,但这并不容易。

您需要做的是编译二进制文件以进行动态绑定;然后根据@cnicutar的答案获得dlsym的功能。

当然有一些警告;但是如果有问题的函数在一个动态链接的库中,并且保证在运行时知道一个路径(插件或扩展模块会匹配这个),那么这是一种相当安全的方法。

活动可执行文件中的dlsyming函数OTOH变得毛茸茸。

答案 3 :(得分:0)

如果必须使用该函数的名称来完成并且您不想使用cnicutar的方式,那么您可以使用此方法:

在每个* .exe文件中编译每个函数。使用系统(PATH_TO_FUNCTION_EXECUTABLE / FUNCTION_NAME)来调用可执行文件。

答案 4 :(得分:0)

如果您知道需要拨打的所有功能,并将它们放在一个程序中,您可以使用:

void do_fork()
{
    printf ("Fork called.\n");
}

void callFunc(char *funcName)
{
    if (strcmp(funcName, "do_fork") == 0) do_fork();
}

int main()
{
    char *pFunc = "do_fork";
    callFunc(pFunc);
    return 0;
}