lua-users home
lua-l archive

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



Roger D. Vargas wrote:
I was playing with the example about accessing C structures from lua in the wiki and i noticed that objects are created from inside lua scripts. i was wondering if there is a way to create the structure in C and then push it to the lua state as a full userdata.


Here is the simple approach:

  Foo *fp = (Foo*)lua_newuserdata(L, sizeof(Foo));
  fp->x = ...;
  fp->y = ...;
  fp->whatever = something_other_than_this;
  luaL_getmetatable(L, FOO);
  lua_setmetatable(L, -2);
  lua_setglobal(L, "myfoo");

Now when you pass the value of the 'myfoo' variable to some function, it will need to cast the userdata back to a pointer to Foo:

  Foo *fp = (Foo*)luaL_checkudata(L, index, FOO);
  if (fp == NULL) luaL_typerror(L, index, FOO);

I usually wrap these up in 'push' and 'check' functions and think of them analogous to lua_pushnumber and luaL_checknumber.

But I get the feeling you know this already and there is more to your question. If your question is "given some pointer, can I bless it so that it becomes a full userdata without calling lua_newuserdata", then the answer is "no". Just put your pointer inside the userdata in this case.

It can get a little more tricky if there are resources allocated, *and* you need to push the userdata more than once, *and* you want the __gc event to do the clean up, in which case you want to push a unique userdata so that the __gc event only deallocates the resource once.
See http://lua-users.org/lists/lua-l/2001-09/msg00121.html

Also if you manually deallocate the resouce, you'll need to indicate this somehow so that the __gc event doesn't deallocate the resource again. See lua-5.0/src/lib/liolib.c

- Peter