我想通过名称动态调用函数,例如,假设有以下函数和字符串:
void do_fork()
{
printf ("Fork called.\n");
}
char *pFunc = "do_fork";
现在我需要do_fork()
致电*pFunc
。那可能吗?
欢迎使用C / C ++代码,非常感谢!
答案 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::function
和std::bind
而不是普通函数指针,可以稍微提升此限制(以包含合理兼容的签名)。
答案 1 :(得分:4)
不完全确定这是否是您正在寻找的内容,但您可以轻松使用dlopen
和dlsym
。
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;
}