views:

520

answers:

8

I have several functions in my program that look like this:

void foo(int x, int y)

Now I want my program to take a string that looks like:

foo(3, 5)

And execute the corresponding function. What's the most straightforward way to implement this?

When I say straightforward, I mean reasonably extensible and elegant, but it shouldn't take too long to code up.

Edit:

While using a real scripting language would of course solve my problem, I'd still like to know if there is a quick way to implement this in pure C++.

+8  A: 

You could take a look at Lua.

Daniel
look at Lua - to do WHAT ??? That page is close to useless to describe how to embed the language. Even page 3 of the manual (http://www.lua.org/manual/5.1/manual.html#3) closer but doesn't help the OP.
jim
"Use lua" is becoming a knee-jerk reaction to similar questions.
artificialidiot
+10  A: 

You can embed Python fairly simply, and that would give you a really powerful, extensible way to script your program. You can use the following to easily (more or less) expose your C++ code to Python:

I personally use Boost Python and I'm happy with it, but it is slow to compile and can be difficult to debug.

Simon Steele
SWIG is very good and very flexible.
Vardhan Varma
+3  A: 

As Daniel said:

Script languages like Lua and Python would be the most used script languages for binding together c++ libraries.

You will have to add a script interface to your c++ application. The buildup of this interface obviously depends on what script language you chose.

Nailer
+1  A: 

If you only wish to call a function by literal name, you could use linker-specific functions.

On POSIX-compliant operating systems (like Linux), you can use dlopen() and dlsym(). You simply parse the input string and figure out the function name and arguments. Then you can ask the linker to find the function by name using dlsym().

On Windows however, these functions aren't available (unless there's some POSIX environment around, like Cygwin). But you can use the Windows API.

You can take a look here for details on these things: http://en.wikipedia.org/wiki/Dynamic_loading

Eduard - Gabriel Munteanu
+5  A: 

I'd also go for the scripting language answer.

Using pure C++, i would probably use a parser generator, which will will get the token and grammar rules, and will give me C code that exactly can parse the given function call language, and provides me with an syntax tree of that call. flex can be used to tokenize an input, and bison can be used to parse the tokens and transform them into an syntax tree. Alternatively to that approach, Boost Spirit can be used to parse the function call language too. I have never used any of these tools, but have worked on programs that use them, thus i somewhat know what i would use in case i had to solve that problem.

For very simple cases, you could change your syntax to this:

func_name arg1, arg2

Then you can use:

std::istringstream str(line);
std::string fun_name; str >> fun_name;
map[fun_name](tokenize_args(str));

The map would be a

std::map<std::string, boost::function<void(std::vector<std::string>)> > map;

Which would be populated with the functions at the start of your program. tokenize_args would just separate the arguments, and return a vector of them as strings. Of course, this is very primitive, but i think it's reasonable if all you want is some way to call a function (of course, if you want really script support, this approach won't suffice).

Johannes Schaub - litb
I would go for boost::spirit, as you will learn a lot about parsers and about template metaprogramming.
lothar
A: 

Does your system have to "take a string"? You could expose COM (or CORBA, or whatever) interfaces on your application and have whatever is generating these commands call into your application directly.

kingkongrevenge
+1  A: 

C++ Reflection [2] by Fabio Lombardelli provides full re-flection for C++ through template metaprogramming tech-niques. While it is fully compliant with the C++ standards,it requires the programmer to annotate the classes in order forthem to be reflective

http://cppreflect.sourceforge.net/

otherwise you'd want a function pointer hash table i think

iterationx
+2  A: 

CERN provides CINT, a C/C++ interpreter that can be embedded within your application to provide scripting capabilities.

Josh Kelley