lua-users home
lua-l archive

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


On 09/05/2014 10:53 PM, Flávio Alberto wrote:
Excuse-me, my last e-mail was sent in HTML mode, set in simple text mode...

Hello all
I'm a C/C++ programmer and new to Lua, I'm need a requirement on my
application, I need that a lua script access a previous created global
table and inside this table I need to have more three tables,  these
table creation was made in C system using this code :


static int l_index(lua_State* L)
{
   cout << __FILE__ << " : " << __FUNCTION__ << endl;
   return 1;
}

static int l_newindex(lua_State* L)
{
     cout << __FILE__ << " : " << __FUNCTION__ << endl;
   return 1;
}

static const struct luaL_Reg methods[] = {
{ "__index",       l_index },
{ "__newindex",    l_newindex },
{ NULL,            NULL            }
};


LUALIB_API int luaopen_mastertable (lua_State* L)
{
     luaL_newmetatable(L, "luasystem.mastertable");
   lua_pushvalue(L, -1);

   luaL_register(L, NULL, methods);
   lua_pop(L, 1);
   lua_pushnil(L);

     lua_pushnumber(L,0);
     lua_newtable(L);
     lua_pushliteral(L,"table1");
     lua_newtable(L);

     lua_pushliteral(L,"table2");
     lua_newtable(L);

     lua_pushliteral(L,"table3");
     lua_newtable(L);

     lua_settable(L,-7);
     lua_settable(L,-5);
     lua_settable(L,-3);

     lua_setglobal(L,"mastertable");

   return 1;
}

and in main code I do :

.
.
.
luaopen_mastertable(this->L, NULL, 0);
luaL_loadfile(...);
lua_pcall(...);
.
.
.

When running the folowing script :

print(">> type(mastertable)="..type(mastertable))
print(">> type(mastertable.table1)="..type(mastertable.table1))
print(">> type(mastertable.table2)="..type(mastertable.table2))
print(">> type(mastertable.table3)="..type(mastertable.table3))

mastertable.table1.a = 7
mastertable.table1.b = {}

print(">> mastertable.table1.a="..mastertable.table1.a)


I get the following messages on terminal :
type(mastertable)=table
type(mastertable.table1)=table
type(mastertable.table2)=table
type(mastertable.table3)=table
mastertable.table1.a=7
I look that my C code created the tables OK, but l_index()
l_newindex() were not called.
Whats the problem with the registration of these calls ? What is the
correct way to do this ?

Thanks for any help
Success

Flávio Lopes

luaL_newmetatable would only create (or reuse pre-existing) a table to be used as a
metatable and store it into the registry using the given tname as key.
you still need to call lua_setmetatable.

besides, metatables for tables and full userdata are in per-instance basis, you need
to call lua_setmetatable on each table instance you want to associate the metatable.

yet metatables for other builtin data types (boolean, number, etc) are per-type, which
means all the values of the same type share the same metatable, so you need only
call lua_setmetatable once on any value of that type.

in your example, if you want register the metatable for `mastertable.table1`:

~~~~

<...>

lua_newtable(L); // create 'mastertable'

lua_newtable(L); // create 'table1'
luaL_getmetatable(L, "tname of your metatable"); // get metatable from the registry
lua_setmetatable(L, -2); // setmetatable(table1, __mt)
lua_setfield(L, -2, "table1");

lua_newtable(L);
lua_setfield(L, -2, "table2");

lua_newtable(L);
lua_setfield(L, -2, "table3);

lua_setglobal(L,"mastertable");

<...>

~~~~

thus, ``mastertable.table1.a = 7`` would trigger the __newindex metamethod, and
``print(mastertable.table1.a)`` would trigger the __index metamethod, and would
print out 'nil', as the __index metamethod returned nothing, but Lua would adjust
it into 1 value, resulting the 'nil'