Archive 17/01/2023.

Binding C++ code to Lua script API

setzer22

Hello,

EDIT: As I consider my questions were too vague, I made a reply asking for specific things after understanding a bit better how everything works with lua.

I’m learning Lua with Urho3D and right now I’m trying to bind my custom component’s API to the Lua script subsystem.

I’m reading through tolua++'s documentation and I get how it works: You provide it “cleaned up” header files it can parse and then generate auto binding code. But the problem is that I don’t know exactly how does Urho register its API.

My question is, How would I go into registering my own API with pkg files, and adapt my build system so the bindings are generated, just like Urho does?

My main concern is how should I go with including the Urho3D headers so tolua++ can use Urho’s types. For example if I’m using RigidBody in my component, does the pkg file need that reference? Or that’s just for my own defined classes (as Urho types are already bound by the engine).

Thank you! :smiley:

setzer22

With some help from the IRC, I’ve been able to understand a bit more how tolua++ works and when it’s called by Urho. Now I’m able to ask more specific questions.

-  If I understood correctly, each call to tolua++ generates a C file with a function that receives a pointer to the lua "context" (actually called lua_state). That function adds everything that needs to be added to the Lua state. Am I right?

- In order to actually do the binding, I should get the lua_state pointer (from the LuaScript class) and call the C generated function with it. To do so I can load the C generated function as an extern symbol into my game code, right?

- Given Lua's weak typing, anything that's not a basic type (like int or float) will be interpreted as a table, so there's no need to include all the files that depend on a given pkg, for example, if a function receives an Urho3D::Rigidbody* as a parameter on the C++ side, ToLua++ will just interpret that as a table, and then it's the lua programmer's fault if it calls it with the wrong data. Did I get this right?

- Due to my last point, I just assumed pkg includes in tolua++ are just a convenience so I can generate a C file that binds a bunch of classes right? In my case, would it be OK to just make a pkg that includes all the other pkgs so I generate a single C file to bind them all? (i.e. one C file to rule them all, and into the engine bind them... Sorry I couldn't help it  :smiley: ).

- Do I have to do anything special to deal with String, Vector and the likes? I assume Urho just maps those types to its lua equivalents. If my pkgs just reference Urho3D::String and Urho3D::Vector without doing anything else will I get that behaviour?

- Lastly, I saw some pkg files in Urho's source including header files and using "using namespace". That is done so the generated code is able to retrieve those symbols, right? In my case, all those symbols should already be in in memory when compiling the file, so there's no need for a .h include right?.
setzer22

In order to share my knowledge to future readers I’ll just answer my own questions with what I’ve found out by trial and error:

All what I said above works just as I expected. I just need to get the lua_state from the LuaScript subsystem after its instantiation and call the external function generated by tolua++. That makes the C++ API available to my Lua scripts.

[quote]- Given Lua’s weak typing, anything that’s not a basic type (like int or float) will be interpreted as a table, so there’s no need to include all the files that depend on a given pkg, for example, if a function receives an Urho3D::Rigidbody* as a parameter on the C++ side, ToLua++ will just interpret that as a table, and then it’s the lua programmer’s fault if it calls it with the wrong data. Did I get this right?

  • Do I have to do anything special to deal with String, Vector and the likes? I assume Urho just maps those types to its lua equivalents. If my pkgs just reference Urho3D::String and Urho3D::Vector without doing anything else will I get that behaviour?[/quote]

Regarding all that, I’ve found out most of it is true. Sadly you can pass any type to the C++ side from Lua, and you can get a lot of crashes from silly mistakes as well. But that’s what comes with such a weak typing system in combination with C++ I guess. I think URH3D_SAFE_LUA flag prevents some of those.

Even though, some types are not interpreted as tables but userdata, which is then handled with metatables.

Also, I had to do nothing to deal with Strings or Vectors, those seem to be already handled by ToLua++. I’ve had to call it with the command line option “-L ToCppHook.lua”, and I think all this is handled there.

There seems to be two kinds of includes in tolua++. There are the $pfile includes, which load a package file, and generate bindings for those as well in the same binder C code. Then there’s also $#include and $using, when those are present in a pkg file, they’re copied to the generated C code.

In order for all symbols to be present in memory I’ve found useful to do (in MyComponent.pkg): $#include “MyComponent.h”. Also for that to work you should include the same $using directrives you have in your header file (I think).

And that’s all. I still don’t know much of the lua bindings, but I’ll try to make a small guide when I’m a bit more knowledgeable on the topic!

ezark

Maybe it is created in the Urho3d/CMakeLists.txt.
tolua++ uses .pkg file to generate ${DIR}LuaAPI.cpp.