我想使用字串值來呼叫函式。這可能嗎?有人可以展示一些實作。我會很感激。
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;
}
我正在撰寫一個收集度量資料的程式。我想為特定指標執行特定功能。我會將所有函式命名為與指標名稱相同的名稱,這樣當我將指標名稱作為輸入(字串)時,它會執行特定的函式。我不希望 if-else 基于度量名稱輸入來執行函式,因為我的程式正在收集超過一百個度量。擁有可能的 if-else 看起來會很尷尬。這就是為什么我試圖以這種方式做某事。
想要適用于兩個作業系統 windows/linux 的東西
uj5u.com熱心網友回復:
一種解決方案是創建從函式名稱到函式本身的映射。我們知道函式在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.so
- 從
main.cpp.
$ g main.cpp -ldl -o main
- 運行并檢查結果。
$ ./main
3
-1
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/513356.html
上一篇:佇列大小的差異給出了任意大的值C
