tags:

views:

1115

answers:

4

I am looking at embedding Lua in a C++ application I am developing. My intention is to use Lua to script what ordered operation(s) to perform for some given input, ie. receive a new work item in c++ program, pass details to Lua backend, Lua calls back into c++ to carry out necessary work, returns finished results.

The primary data structure involved is a large (approx 80+ members) struct. I am (very) new to Lua and am unsure of how I can pass it to and from my host application and the embedded Lua state.

Thus far I see my options as:

a) Pushing/Popping all the individual data members onto the stack when crossing to/from C++ and Lua (sounds messy).

b) Constructing a table and populating with the values, then putting that on/off the stack (a little cleaner).

c) Pass it as userdata (light/heavy?) (I'm sketchy on this, and not sure if/how I can then access it from the Lua side to query what operations are necessary).

Any guidance would be greatly appreciated.

+2  A: 

I have not done this myself (it was years since I used Lua, and I've never used in an embedded fashion), but I think you should look into metatables and the userdata type. The manual says this about userdata values:

This type corresponds to a block of raw memory and has no pre-defined operations in Lua, except assignment and identity test. However, by using metatables, the programmer can define operations for userdata values (see §2.8). Userdata values cannot be created or modified in Lua, only through the C API

Sounds about right.

unwind
+3  A: 

If I recall correctly, light userdata is actually just a pointer. They all share the same metatable. They are mostly used to pass around addresses of C data.
Full userdata is probably closer of what you need if you must access it from the Lua side. Their metatable would allow you to access it like it was a regular Lua table, for example.

You might be also interested by Roberto's library for converting data to and from C structs for Lua 5.1. Or not. Depends on your needs... :-)

PhiLho
I was able to cast from lightuser data to an objective-c object. I imagine it would work the same for a struct.
Nick
+1  A: 

Exposing the entire representation to Lua may not be what you want. Maybe you only expose a few operations? Then use a pointer to the struct as light userdata. It cannot have a metatable so you must use explicit functions.

If you want to expose everything, your best bet is probably to push a full userdata containing only a pointer to the struct. This means an extra level of indirection---lost in the noise from a performance point of view, but easy to get wrong, so maintain a single point of truth where you cross the C++/Lua boundary.

With full userdata you can use macros (the horror!) to put gettter and setter functions for each field. This is a lot of work to do by hand, and you may prefer to check out tolua++ even though it comes with a lot of baggage.

Go to the Lua mailing list!

Norman Ramsey
A: 

If I where you, I would pass around a reference to the struct and then let Lua call C functions to modify it. This also means that you can upgrade the system with less hassle than if Lua has to know all the details of the underlying system.

tomjen