One solution is to create a mapping from function name to function itself. We know that a function is a pointer in C/C++, so we can easily do this after confirming the type of the function pointer. In your case, the target function type is int (*)(obj).
Code snippet:
#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; }
Edit: Update according to the comment, use dynamic shared library to avoid manually creating the mapping. I assume you are using Linux.
First, move class definition and the type of target functions into a separated header obj.hpp:
class obj { public: int num1; int num2; }; // type of target functions typedef int (*ftype)(obj);
Collect target functions to a separated file functions.cpp to build dynamic shared library.
#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; }
In the third file main.cpp, we retrieve functions from the library according to the function name.
#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; }
- Build a dynamic shared library from
functions.cpp.
$ g++ functions.cpp -shared -fPIC -o functions.so
- Build an executable file from
main.cpp.
$ g++ main.cpp -ldl -o main
- Run and check the results.
$ ./main 3 -1
eval()for C++... right?