lua-users home
lua-l archive

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


This is the code that's used in the example:

int Image_register (lua_State *L)
{
  luaL_openlib(L, IMAGE, Image_methods, 0);  /* create methods table,
                                                add it to the globals */
  luaL_newmetatable(L, IMAGE);        /* create metatable for Image,
                                         add it to the Lua registry */
  luaL_openlib(L, 0, Image_meta, 0);  /* fill metatable */
  lua_pushliteral(L, "__index");
  lua_pushvalue(L, -3);               /* dup methods table*/
  lua_rawset(L, -3);                  /* metatable.__index = methods */
  lua_pushliteral(L, "__metatable");
  lua_pushvalue(L, -3);               /* dup methods table*/
  lua_rawset(L, -3);                  /* hide metatable:
                                         metatable.__metatable = methods */
  lua_pop(L, 1);                      /* drop metatable */
  return 1;                           /* return methods on the stack */
}

This is the code I use:

int lluaopen_user (lua_State *L) {
 luaL_openlib(L, "user", llua_user_f, 0);
 luaL_newmetatable(L, TYPE);
 luaL_openlib(L, 0, llua_user_m, 0); /* mt */

 lua_pushliteral(L, "__index");
 lua_pushvalue(L, -3);
 lua_rawset(L, -3);

 lua_pushliteral(L, "__metatable");
 lua_pushvalue(L, -3);
 lua_rawset(L, -3);

 lua_pop(L, 1);
 return 1;
}

TYPE is defined as "L2.user".

The GD binding example code works in 5.1 (the methods work), but they
don't in my code so there must be something I'm doing differently...
but what? Reading your Delphi code didn't really help me (I don't have
a C function for __index, and I couldn't exactly figure out what to do
instead). Should I open the library in a certain way?

Anders

On 4/12/06, jdarling@eonclash.com <jdarling@eonclash.com> wrote:
> No idea, I'm still using Lua 5.0.2 but used the LUNA 5.1 as a reference
> point for my wrapper classes.  Hopefully this means that I'm ready for
> 5.1 when the headers are converted :).
>
>  - Jeremy
>
> "Help I suffer from the oxymoron Corporate Security."
>
>
> > -------- Original Message --------
> > Subject: Re: Problem with userdata (metatable)
> > From: "Anders Bergh" <anders@anders1.org>
> > Date: Wed, April 12, 2006 11:17 am
> > To: "Lua list" <lua@bazar2.conectiva.com.br>
> >
> > I'm going to test what you did in your Delphi code, and test it in my
> > code to see if it works. How come the
> > http://lua-users.org/wiki/UserDataWithPointerExample example doesn't
> > work though? Did things change in Lua 5.1?
> >
> > Anders
> >
> > On 4/12/06, jdarling@eonclash.com <jdarling@eonclash.com> wrote:
> > > Since you in C/C++ take a look at how LUNA is doing things.  I'm no
> > > vertran myself, but I have had some problems with methods in Delphi
> > > (actually enough that I believe I see your problem).
> > >
> > > You need to track your methods table, object meta table, and object
> > > table.  For example some working code of mine (note again Delphi not C)
> > > is:
> > >
> > > procedure RegisterMyClass(LuaScript:TLUAWrapper);
> > > var
> > >   MetaTable,
> > >   MethodTable,
> > >   Methods : Integer;
> > > begin
> > >   lua_newtable(LuaScript.LuaState);
> > >   Methods := lua_gettop(LuaScript.LuaState);
> > >
> > > // Lua<#ClassName#>ClassName - represents the class name in text
> > >   luaL_newmetatable(LuaScript.LuaState, Lua<#ClassName#>ClassName);
> > >   MetaTable := lua_gettop(LuaScript.LuaState);
> > >
> > >   lua_pushstring(LuaScript.LuaState, Lua<#ClassName#>ClassName);
> > >   lua_pushvalue(LuaScript.LuaState, Methods);
> > >   lua_settable(LuaScript.LuaState, LUA_GLOBALSINDEX);
> > >
> > >   lua_pushliteral(LuaScript.LuaState, '__metatable');
> > >   lua_pushvalue(LuaScript.LuaState, Methods);
> > >   lua_settable(LuaScript.LuaState, MetaTable);
> > >
> > >   lua_pushliteral(LuaScript.LuaState, '__index');
> > >   lua_pushcfunction(LuaScript.LuaState, index_<#ClassName#>);
> > >   lua_settable(LuaScript.LuaState, MetaTable);
> > >
> > >   lua_pushliteral(LuaScript.LuaState, '__newindex');
> > >   lua_pushcfunction(LuaScript.LuaState, newindex_<#ClassName#>);
> > >   lua_settable(LuaScript.LuaState, MetaTable);
> > >
> > >   lua_pushliteral(LuaScript.LuaState, '__gc');
> > >   lua_pushcfunction(LuaScript.LuaState, gc_<#ClassName#>);
> > >   lua_settable(LuaScript.LuaState, MetaTable);
> > >
> > >   lua_newtable(LuaScript.LuaState);
> > >   MethodTable := lua_gettop(LuaScript.LuaState);
> > >   lua_pushliteral(LuaScript.LuaState, '__call');
> > >   lua_pushcfunction(LuaScript.LuaState, new_<#ClassName#>);
> > >   lua_pushliteral(LuaScript.LuaState, '__new');
> > >   lua_pushvalue(LuaScript.LuaState, -2);
> > >   lua_settable(LuaScript.LuaState, Methods);
> > >   lua_settable(LuaScript.LuaState, MethodTable);
> > >   lua_setmetatable(LuaScript.LuaState, Methods);
> > >
> > > // for each method that you want to register
> > >   lua_pushcfunction(LuaScript.LuaState, lua<#ClassName#><#MethodName#>);
> > >   lua_settable(LuaScript.LuaState, Methods);
> > > // end of for each method
> > >
> > >   lua_pop(LuaScript.LuaState, 2);
> > > end;
> > >
> > >  - Jeremy
> > >
> > > "Help I suffer from the oxymoron Corporate Security."
> > >
> > >
> > > > -------- Original Message --------
> > > > Subject: Problem with userdata (metatable)
> > > > From: "Anders Bergh" <anders@anders1.org>
> > > > Date: Wed, April 12, 2006 8:25 am
> > > > To: "Lua list" <lua@bazar2.conectiva.com.br>
> > > >
> > > > Hi!
> > > >
> > > > I'm using Lua 5.1 and I've been trying to add my own userdata type. It
> > > > works except I couldn't get methods working. I've been reading the
> > > > chapter in the first edition of pil and
> > > > http://lua-users.org/wiki/UserDataWithPointerExample.
> > > >
> > > > Here's the code I use:
> > > >
> > > > static const luaL_reg llua_user_f[] = {
> > > >   /* Functions */
> > > >   {"FindByNick", llua_user_FindByNick},
> > > >
> > > >   /* Methods */
> > > >   {"GetNick", llua_user_GetNick},
> > > >   {NULL, NULL}
> > > > };
> > > >
> > > > /* Metatable */
> > > > static const luaL_reg llua_user_m[] = {
> > > >   {"__tostring", llua_user_tostring},
> > > >   {NULL, NULL}
> > > > };
> > > >
> > > > int lluaopen_user (lua_State *L) {
> > > >   luaL_openlib(L, "user", llua_user_f, 0);
> > > >   luaL_newmetatable(L, TYPE);
> > > >   luaL_openlib(L, 0, llua_user_m, 0); /* mt */
> > > >
> > > >   lua_pushliteral(L, "__index");
> > > >   lua_pushvalue(L, -3);
> > > >   lua_rawset(L, -3);
> > > >
> > > >   lua_pushliteral(L, "__metatable");
> > > >   lua_pushvalue(L, -3);
> > > >   lua_rawset(L, -3);
> > > >
> > > >   lua_pop(L, 1);
> > > >   return 1;
> > > > }
> > > >
> > > > When I use "user:GetNick()" in Lua, I get the error: attempt to index
> > > > field '?' (a nil value).
> > > >
> > > > getmetatable(user) returns nil, tostring(user) returns "user:
> > > > 0x815598c". What exactly am I doing wrong?
> > > >
> > > > Anders
> > >
> > >
>
>