Call a function using a string containing the function name

I have a class defined as

class modify_field { public: std::string modify(std::string str) { return str; } }; 

Is there a way to store this function name inside a string in the main function and then call it. I tried this, but it does not work.

 int main() { modify_field mf; std::string str,str1,str2; str = fetch_function_name(); //fetch_function_name() returns string modify str2 = "check"; cout << str; //prints modify str1 = str + "(" +str2 + ")"; mf.str1(); } 

I know this is wrong. But I just want to know if there is a way to call the function name using a variable.

+4
source share
6 answers

In C ++, this is not possible. C ++ is a compiled language, so the names of functions and variables are not present in the executable file - so the code cannot associate your string with the name of the function.

You can get a similar effect using function pointers, but in your case you are also trying to use a member function, which complicates things a bit.

I will give a small example, but I want to get an answer before spending 10 minutes writing code.

Edit: here is some code to show what I mean:

 #include <algorithm> #include <string> #include <iostream> #include <functional> class modify_field { public: std::string modify(std::string str) { return str; } std::string reverse(std::string str) { std::reverse(str.begin(), str.end()); return str; } }; typedef std::function<std::string(modify_field&, std::string)> funcptr; funcptr fetch_function(std::string select) { if (select == "forward") return &modify_field::modify; if (select == "reverse") return &modify_field::reverse; return 0; } int main() { modify_field mf; std::string example = "CAT"; funcptr fptr = fetch_function("forward"); std::cout << "Normal: " << fptr(mf, example) << std::endl; fptr = fetch_function("reverse"); std::cout << "Reverse: " << fptr(mf, example) << std::endl; } 

Of course, if you want to save functions in map<std::string, funcptr> , this is entirely possible.

+6
source

You have two options:

1 - manually create a map with pointers to the functions you need and their identifiers in the form of a string key so that you can search or ...

2 - create a dynamic link library / shared object and use a name lookup to get a pointer. Use extern "C" to prohibit id manipulation. You may not be able to use some of the C ++ features, and the performance will be slightly worse, depending on your actual use case.

+3
source

Of course, it is possible with C functions, but it will be very difficult and not portable for C ++, because different operating systems (and even different compilers in the same OS) use different ABIs for C ++, so the names of real functions are significantly different from what you called them in your code.

If the C functions are fine (for example, you can declare them as extern "C"), you can use dlsym for POSIX and GetProcAddress for windows. Of course, you need to add these functions to the dynamic symbol table - something like the -rdynamic flag for ld or __declspec (dllexport) (I hope this was correct - it was not used if for a long time) on the windows.

+2
source

Perhaps a pointer to this function is more adequate. This allows you to easily choose between functions to call:

 #include<iostream> using namespace std; class modify_field { public: std::string modify_1(std::string str) { return str; } std::string modify_2(std::string str) { return str + str; } }; int main() { string (modify_field::* fun_ptr) (string) = &modify_field::modify_1; modify_field m; cout << (m.*fun_ptr)("test") << endl; fun_ptr = &modify_field::modify_2; cout << (m.*fun_ptr)("test") << endl; } 
+1
source

If the functions have the same signature, you can create a line map for std :: function objects. More about std :: function here: std :: function

0
source

If you placed all the functions that you would like to search by name in the set of source files that you then generated using the DLL, you can use the dlopen() and dlsym() functions to find the entry point.

An example of how to do this can be found on the dlsym() manual pages on your computer, or you can refer to this link .

This only works on functions that are not related (for example, with C ++ you may have some problems). You may need to define these entry points as "extern C" to prevent mangling, or come up with some other mechanism to guess the garbled name for the C ++ entry point. I never did the latter, so there are some nuances that I do not pay attention to.

If you use Windows (it was not clear which OS you are on), you should find the GetProcAddress() documentation, which is available online here .

A good tutorial on this subject in general, and this story on how to do all this with C ++ can be found here .

0
source

Source: https://habr.com/ru/post/1498931/


All Articles