Reputation: 605
I'm not sure if my question makes any sense, but I certainly know it is near impossible to get the results from Google. Firstly, what I do not want. I don't want to call some function that prints "hello world" or adds two numbers together, I want to load a Lua script from a C++ program, but allow the script to modify variables of the C++ program, using functions. For example, imagine I have a C++ program like this:
class Foo
{
private:
int number = 0;
public:
void setNumber(const int& newNumber) {number = newNumber;}
}
int main()
{
Foo foo;
//Load and execute Lua script, with foo object
return 0;
}
How could I allow the Lua script to do foo.setNumber()
(preferably without foo.
)? This may be a very simple question, but as mentioned above, almost all information on Google when searching "Call C++ Function from Lua" assume there is no program, but just a .cpp/hpp file with some functions that you want to call.
I'm on Linux (Ubuntu), but the program needs to compile on all platforms (Windows and Mac)
Upvotes: 2
Views: 1345
Reputation: 29021
This is asked here fairly regularly.
To roll your own binding you should:
Broadly, you expose a C++ class instance to Lua by creating a Lua "userdata" containing a pointer to the class instance and passing this to the Lua script. A userdata is an opaque type; the Lua script can't actually do anything with it (other than pass it around) unless you give it a metatable. At the very least you must implement the __index
metamethod on the userdata, which allows your C++ code to intercept attempts to index the userdata and return something meaningful, and the __gc
metamethod, which allows your C++ code to delete the exposed C++ object when the corresponding Lua userdata is garbage collected.
For instance, you create a function called createFoo
which creates a Foo
instance, wraps the pointer as a userdata, applies a metatable implementing __index
to it, and returns it to the Lua script.
When the user runs foo.setNumber
, your C++ __index
metamethod is called with the userdata and the string "setNumber". It's up to you what you return and this determines what foo.setNumber
evaluates to in the Lua script. You want foo.setNumber
to evaluate to a lua_CFunction
which expects a Foo
userdata as its first parameter, so that your class methods can be called idiomatically from Lua (i.e. foo:setNumber(12)
, which is syntax sugar for foo.setNumber(foo, 12)
).
It's a very low level and manual process, and once you get the hang of it you're going to end up create a library/templates/macros whatever to do the boilerplate for you. At that point you may want to evaluate the myriad C++ binding libraries that exist. However, thanks to the Law of Leaky Abstractions it's a very good idea to learn to do this manually first.
Upvotes: 4