lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


On Wed, Oct 25, 2006 at 06:18:07PM +0200, Matthias Isele wrote:
> Hi everybody,
> I've got a lua problem.
> There are two c/c++ structs:
> 
> typedef struct structA
> {
>    int a;
>    int b;
> };
> 
> typedef struct structB;
> {
>    int x;
>    int y;
>    structA   anotherStruct;
> };
> 
> I can access any struct element in lua with the following notation:
> structA.a = 1
> structA.b = 2
> and
> structB.x = 3
> structB.y = 4
> Until here everything works fine.
> 
> Now the tricky part (and also my question):
> how can I access the structB in structA in a notation like:
> 
> structB.anotherStruct.a = 5   in lua.
> 
> 
> Here's how I implemented the structs:

I think you posted the wrong code, it's the code for structB thats
important, particularly the call to lua_newuserdata().

Exactly how to do this depends on how you use these user-datas, but
I think basically what you need to do is return a userdata

  proxy = structB.anotherStruct
  proxy.a = 3

proxy needs to not have a pointer to the structB memory, but instead
have a lua reference, so that it can look B up, and set the correct
struct elements, have you seen http://www.lua.org/pil/27.3.2.html?

It might be possible to change things so what I call "proxy" above
is the same as the structA wrapper, except that it would operate in
two modes, one it "owned" the memory, the other it just had a pointer
to another object.

Hope that helps a bit, and didn't just repeat stuff you knew.

Also, if you don't actually need to keep the C struct around as memory,
another option might be to just represent it in lua as tables. pseudo-C code:

  void create_from_structB(lua_State* L, struct structB* b)
  {
	  lua_newtable(L)
	  // do table.a = b->structA.a, I probably have this code all wrong,
	  // its from memory
	  lua_push(L, "a");
	  lua_push(L, b->structA.a)
	  lua_settable(L, -3);
	  // again for "b"

	  lua_newtable(L) // the table for B 
	  // set x to b->x
	  // set y to b->y
	  // anotherStruct to the first table created above
  }

There are a few times where I've made user-data, then though, why? I can
represent this data as tables in lua, so they everything tables do
already. Then if they are passed as args to C functions, those C
functions can convert the tables back into the underlying C data
structers, as necessary. This also allows  things like:

  b = StructB.new{
	  x = 1,
	  y = 2,
	  anotherStruct = {
		  a = 4,
		  b = 5,
	  }
  }

Cheers,
Sam