Page 1 of 1

C++ execute functions whos name resides in a variable

Posted: Sat Oct 30, 2004 10:53 pm
by Keeper
in c++, how do you run a fuction, if the functions name is in a varibal. basicly, i want to execute the function who name is in a varibal.

like:

variable_value(); //This is a function

Re:C++ execute functions whos name resides in a variable

Posted: Sun Oct 31, 2004 10:24 am
by mystran
Surprisingly enough, if you have a function pointer called fp,
then you can call it by dereferencing the pointer and calling the result as in:

void bar() {
printf("in bar (drinking straight tequila)\n");
}
int main() {
void (*fp)() = bar; // define/initialize the function pointer
(*fp)(); // call the function through the function pointer
return 0;
}

This would work in C too..
Now, actually you don't need to write (*fp) because function pointers are converted automatically, so that fp() means the same as (*fp)(). Anyway, google for "function pointer" and you'll find some more information.

Re:C++ execute functions whos name resides in a variable

Posted: Sun Oct 31, 2004 11:50 pm
by Candy

Code: Select all

   void (*fp)() = &bar; // define/initialize the function pointer 
actually...

Yet if you only know the name of the variable, say

Code: Select all

std::string fname = "bar";
void (*fp)() = do_something_call(fname);
fp();
all you needed to do was define do_something_call, that received a functions name and wanted a pointer to it. The solution is to mangle it using the most probable locales at that point (use debugging info) and to try to match those using default dynamic linking functions.

Of course, always requiring full locale specification (bar::something::bar()) would be best.

Re:C++ execute functions whos name resides in a variable

Posted: Mon Nov 01, 2004 6:41 am
by Solar
Some explanation is necessary, I think...

In C++, a function foo() can exist in several namespaces, several classes, and even within a single class it can be overloaded multiple times for various parameter types.

Thus, the name of a function isn't as unambiguous as it is in some other languages. You can narrow it down with scope operators (namespace::class::function), but that still leaves overloading.

Thus, the compiler "mangles" C++ function names to include information on namespace, class, and parameter types - unfortunately rendering it unintelligible for human readers. But then, the one having to "read" it isn't human, but the linker.

On the downside, that doesn't give you any "easy" way to call a function in the way you described.

Candy suggested writing a function that takes a string, does the "magic mangling", and returns a function pointer. Unfortunately, that wouldn't work, since without the parameter type information you can't come up with the correct mangled name.

No cigar; no standard-compliant way to do so. On Unixoid systems, you might want to look into dlopen() and its ilk, which offer a way of loading a shared lib, getting a handle on that lib, and querying that handle for a function identified by name.

Re:C++ execute functions whos name resides in a variable

Posted: Mon Nov 01, 2004 10:05 am
by df
couldnt you extern "C" the function name to get an unmangled name? but then again, it might not know which one you want if you have several different namespaces.....

Re:C++ execute functions whos name resides in a variable

Posted: Mon Nov 01, 2004 10:59 pm
by zloba
exactly the same question was discussed some time ago

if you have a specific set of user-defined functions of the same type, and want to call them given a name as a string, then my solution would be to create a map (name => function pointer) at startup, and then find and call the function pointer.

of course, if the set is not so specific, then it really depends on what you're trying to do, how and whether that is a good idea. given the lack of information...
[hr]
as for mangling, i think that's too messy and non-portable, as Solar said. it's just not meant for that kinda thing.

even if you somehow had a good way to get the mangled name, you'd still have to (1) feed that same name to the program (aka do the mangling at runtime (!) ), and (2)generate the call instructions. which is pretty much writing another compiler. otherwise, fat lot of good will that mangled name and/or function pointer be if you can't call it.

a scripting language with eval() would be more appropriate for this.

Re:C++ execute functions whos name resides in a variable

Posted: Tue Nov 02, 2004 3:50 am
by Solar
df wrote: couldnt you extern "C" the function name to get an unmangled name?
Yes, but that's no longer C++. ;)

Re:C++ execute functions whos name resides in a variable

Posted: Tue Nov 02, 2004 5:54 pm
by Candy
the entire point of this question was the C++ part of it. The C part of finding a function with a given std::string name had been discussed before, twice, and should now be known, or at least found on a search.

The C++ specific part is mostly the mangling, which includes the class/namespace scope, identifiers, templating, arguments and in some cases even more. A name such as class::func(int x, short int z); could become __ZN5class4funcEit instead of class_func which most humans would like to see. Since there is a structure in these things you can specify what the arguments could contain...

You could ignore polymorphism and only match the start of the function. That gives you a nice matchable and easy to make mangling (relatively, non templatized) that matches all those functions. You could try to insert a simple matching with the parameter count, but that wouldn't be really good. You are best off with the entire signature as Solar already said.

Re:C++ execute functions whos name resides in a variable

Posted: Wed Nov 03, 2004 12:27 am
by mystran
Candy wrote:

Code: Select all

   void (*fp)() = &bar; // define/initialize the function pointer 
actually...
IANALL (I am not a language lawyer) but AFAIK function name acts as the address just like array name acts like the address of the array. That is:

Code: Select all

   void (*fp)() = bar;
   char a[] = "foobar";
   char * ap = a;
is functionally identical to:

Code: Select all

   void (*fp)() = &bar;
   char a[] = "foobar";
   char * ap = &a;
It is perfectly valid in C, and it is perfectly valid in C++ too. It has always been this way, and probably always will. I am too lazy to quote the relevant part from the standards right now, but I promise that if you search hard enough you will find one. :)