Dear. Mr. Conner,
My main application is C++, and it embeds lua (though sometimes it relinquishes full control to a lua loop), so I needed something a bit strong to handle my needs.
Thusly, Yes[1]. Given this lua code:
function f (num_value, a)
return num_value * 2, a:bark()
end
nested = { variables = { no = { problem = 10 } } }
And a sprinkling of C++ code that we'd like to call from Lua that has the exact same behavior:
struct A {
int a = 0xA;
virtual int bark() { return 1; }
};
std::tuple<int, int> bark(int num_value, A* a) {
return std::tuple<int, int>( num_value * 2, a->bark() );
}
You can start things off and do the following, which creates lua state and sets up a new userdata to behave as you would expect from the given lua:
sol::state lua;
lua.script( script_string );
// can also do lua.script_file( file_name ); too
lua.new_usertype<A>( "A",
"bark", &A::bark
); // have a struct and its functions set into this table (coincidentally, it's the global table)
// set the C++ function "bark" to lua identifier "g"
lua.set_function("g", bark);
The following code will do (I believe) what you ask for, calling both a lua function and a C++ function with the (table-nested) lua variable and the C++ variable:
sol::function cpp_bark = lua["f"];
sol::function lua_bark = lua["g"];
sol::reference lua_variable_x = lua["nested"]["variables"]["no"]["problem"];
A cpp_variable_y;
std::tuple<int, int> cppresult = cpp_bark(lua_variable_x, cpp_variable_y);
std::pair<int, int> luaresult = lua_bark(lua_variable_x, cpp_variable_y);
This returns the correct result for both cppresult, which calls the C++ function, and luaresult, which handles multiple returns from lua and returns those as well (expected: a pairing of { 20, 1 }). The example here is a bit squished since I wanted to pack it dense, but I can guarantee you the amount of code you'd write in the plain C API would be a bit of a heartbreaker to achieve the same effect.
Note that the actual code actually "registers" the usertype "A" into lua. If you wanted this code to be tiny, you could remove that part of the example and .
- ThePhD