我想知道是否有人知道如何完成以下任务:
假设我有一堆数据存储在SQL中,可以说其中一个字段可以被称为funcName,函数名称将包含类似于“myFunction”的数据我想知道的是,有什么方法可以比反过来提取函数名称并实际调用该函数?
我可以通过几种方式来实现这一目标,一种是将funcName更改为funcId并与数组或类似链接,但我正在寻找一些更动态的东西,这将允许我添加数据每次我添加对新函数的调用时都不需要更新实际的源代码,当然假设函数已经存在并且可以通过我们从中调用它的范围位置访问。
非常感谢任何帮助。
答案 0 :(得分:3)
使用宏来定义自动注册的新功能。
// callable_function.h
class CallableFunction {
public:
virtual void operator()() = 0;
};
class CallableFunctionRegistry {
public:
static CallableFunction *Register(const string &func_name,
CallableFunction *func_impl) {
Instance()->registered_functions_.insert(make_pair(func_name, func_impl));
}
static void Run(const string &func_name) {
(*Instance()->registered_functions_[func_name])();
}
private:
static CallableFunctionRegistry *Instance() {
static CallableFunctionRegistry *instance = new CallablefunctionRegistry;
return instance;
}
CallableFunctionRegistry() {}
map<string, CallableFunction*> registered_functions_;
};
#define REGISTER_CALLABLE_FUNCTION(FuncName) \
class FuncName : public CallableFunction { \
public: \
virtual void operator()(); \
}; \
CallableFunction *impl_ ##FuncName = \
CallableFunctionRegistry::Register(#FuncName, new FuncName); \
void FuncName::operator()()
并像这样使用它:
//other_file.cc
REGISTER_CALLABLE_FUNCTION(DoStuff) {
// do stuff here.
}
而且:
//yet_another_file.cc
CallableFunctionRegistry::Run("DoStuff");
你可以用函数ptrs而不是CallableFunction对象来做,但我的语法是模糊的。无论哪种方式,都要为重复注册添加错误检查并找不到查找。
答案 1 :(得分:2)
在程序启动时设置名称到函数指针或函子的映射,然后通过映射查找按名称调用。也可以使用动态库进行扩展。
在编译器/解释器世界中,它被称为symbol table,它通常还包含类型(类/结构),数据声明(变量)和函数描述符(参数和返回类型等)。它还可以根据范围嵌套。
答案 2 :(得分:1)
答案 3 :(得分:1)
方法#1(最复杂):
开发插件系统,包括几个动态链接库(* .dll on win,* .so on linux),以及一些公共函数,它们将告诉您的应用程序该插件支持哪些,函数名称和指针。在启动时扫描插件,构建将函数名称映射到其指针的函数列表。
预计参数数量可变。
方法#2(蛮力): 存储您应该能够在一个动态链接库中调用的所有函数。 当从数据库中提取函数名时,在linux上使用GetProcAddress(win32)或dlsym(?)获取函数指针。
预计参数数量可变的问题。不是最快,也不是最聪明的方式。
方法#3(最灵活): 在您的应用程序中嵌入lua或python口译员 这样,您就可以将整个函数存储在数据库中,并且在调用其中一个函数时不会出现问题。你仍然需要声明你想要访问的功能列表。
这不是傻瓜/黑客证明,但如果你不够小心的话,可能会从数据库中搞砸整个应用程序。