我想使用字符串值来调用函数。这个是可能的吗?有人能给我看看具体的实现吗。我会很感激的。
class obj {
int num1;
int num2;
}
int func1(obj o) {
return o.num1 + o.num2;
}
// This is an example data set. This map would be populated with values in the map below with some piece of code.
std::map<std::string, std::string> funcNameMap = {{"func1", "func1"}};
int someFunction(std::string funcName, obj o) {
// Get the value associated with the string "funcName" i.e. "func1".
// Calls function "func1" with value "o" and returns the value.
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
auto x = someFunciton("func1", o);
std::cout << x << std::endl;
return 0;
}我正在编写一个收集公制数据的程序。我想为特定的度量执行一个特定的函数。我会将所有函数命名为与度量名称相同的函数,以便当我将度量名称命名为输入(string)时,它将执行特定的函数。我不希望if-else用于基于度量名称输入执行函数,因为我的程序正在收集100多个度量。如果-否则的话,这看起来会很尴尬。这就是为什么我要这样做的原因。
想要同时适用于操作系统窗口/linux的东西
发布于 2022-10-01 03:54:33
一个解决方案是创建从函数名到函数本身的映射。我们知道函数是C/C++中的指针,所以在确定函数指针的类型之后,我们可以很容易地做到这一点。在您的示例中,目标函数类型是int (*)(obj)。
代码片段:
#include <iostream>
#include <map>
#include <string>
class obj {
public:
int num1;
int num2;
};
int func1(obj o) { // type: int (*)(obj)
return o.num1 + o.num2;
}
// create the mapping from name to function
std::map<std::string, int (*)(obj)> funcNameMap = {{"func1", func1}};
int someFunction(std::string funcName, obj o) {
// Get the value associated with the string "funcName" i.e. "func1".
// Calls function "func1" with value "o" and returns the value.
auto fn = funcNameMap.at(funcName);
return fn(o);
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
auto x = someFunction("func1", o);
std::cout << x << std::endl;
return 0;
}编辑:根据注释更新,使用动态共享库避免手动创建映射。我想你是在使用Linux。
首先,将类定义和目标函数的类型移到单独的头obj.hpp中。
class obj {
public:
int num1;
int num2;
};
// type of target functions
typedef int (*ftype)(obj);将目标函数收集到一个分离的文件functions.cpp中,以构建动态共享库。
#include "obj.hpp"
extern "C"
int func1(obj o) {
return o.num1 + o.num2;
}
extern "C"
int func2(obj o) {
return o.num1 - o.num2;
}在第三个文件main.cpp中,我们根据函数名从库中检索函数。
#include <iostream>
#include <map>
#include <dlfcn.h>
#include <cassert>
#include "obj.hpp"
// name mapping: public name to inner name
std::map<std::string, std::string> funcNameMap = {{"add", "func1"}, {"sub", "func2"}};
int retrieve_fn(void *dl_handler, std::string funcName, obj o) {
assert(dl_handler != NULL && funcNameMap.count(funcName) != 0);
auto real_fn_name = funcNameMap[funcName];
auto fn = (ftype)dlsym(dl_handler, real_fn_name.c_str());
auto dl_err = dlerror();
if (dl_err) {
std::cerr << "Load failed: " << dl_err << std::endl;
return -999;
}
return fn(o);
}
int main(){
obj o;
o.num1 = 1;
o.num2 = 2;
// open dynamic shared library
auto dl_name = "./functions.so";
auto dl_handler = dlopen(dl_name, RTLD_LAZY);
auto dl_err = dlerror();
if (dl_err) {
std::cerr << "Open failed: " << dl_err << std::endl;
return -1;
}
auto x = retrieve_fn(dl_handler, "add", o);
std::cout << x << std::endl;
x = retrieve_fn(dl_handler, "sub", o);
std::cout << x << std::endl;
dlclose(dl_handler);
return 0;
}functions.cpp.构建动态共享库的
$ g++ functions.cpp -shared -fPIC -o functions.somain.cpp.构建可执行文件的
$ g++ main.cpp -ldl -o main$ ./main
3
-1https://stackoverflow.com/questions/73915510
复制相似问题