Ok, so this may not be the best design decision, and I don’t really want to use something like LuaBind… I was just curious if the following is possible in C++ 03 (C++11 makes it possible with variadic templates). Also, I’m sure this has been asked before, but I couldn’t find a straight answer!
Say I have a helper method to call Lua functions from code:
void CallFunction(char* functionName, ...);
which can potentially accept N number of args (using va_arg or any other method of multiple args)
How can I, if it’s even possible, work out the type of each parameter, and pass it to the appropriate lua_push{type}(); function before calling the desired lua function?
I’m not sure if this can be done with var_arg, because you have to know the type when you grab the parameter, I tried to grab it with void* and pass it to a specialized template, but it tries to pass it to template.
Hopefully someone far better at C++ will have a trick or two!
Thanks heaps
I would consider wrapping your functionality for calling lua functions in a class. It has several benefits that I’ll show you in a second, but first here is a possible implementation idea for it. Please note that I have not tested this code (or even tried to compile it), it was just something I quickly wrote from top of my head based on my previous attempts to do the same thing.
The idea here is that at the time of the construction, the function class will find the function with the name and store it in the registry. The reason why I do it this way, instead of just storing the function name and getting it from the globals index on every invocation, is because this way if some other script at later point would replace the global name with another value (that could be something else than a function), the function object would still refer to the correct function.
Anyways you might wonder why go through the trouble of all this. This method has various benefits:
You now have a self-contained type for dealing with lua function objects. You can pass them around in your code easily, without having to worry about the lua stack or lua internals. It’s also cleaner and less error-prone to write code this way.
Because lua_function overloads op(), you basically have a function object. This has the benefit of being able to use it as a callback for any algorithms or functions that accept them. For instance let’s say you have a
lua_function<int> foo("foo");, and let’s say that the function foo in lua takes two arguments, one double and one string. You can now do this:This is very powerful mechanism, as you can now bind your lua code to existing C++ code without having to write any sort of additional wrapper code.
And as you can see, this also lets you easily get the return value from the lua function. With your earlier idea you’d have to extract the values manually from the stack after calling
CallFunction. The obvious drawback here is though, that only one return value is supported by this class, but if you need more than that, you can easily expand on the idea of this class (i.e. you could make the class take additional template parameters for multiple return types, or you could useboost::anyand return a container of them).