Creating a simple table with Lua tables C API

18,273

As I mentioned in comment, lua_settable() takes care only of one key, value pair. Must repeat that if You need more.

I'd prefer saving the Lua stack space like this:

lua_createtable(L, 0, 4);

lua_pushstring(L, "name");
lua_pushstring(L, row->name);
lua_settable(L, -3);  /* 3rd element from the stack top */

lua_pushstring(L, "date");
lua_pushstring(L, row->date);
lua_settable(L, -3);

lua_pushstring(L, "ip");
lua_pushstring(L, row->ip);
lua_settable(L, -3);

lua_pushstring(L, "custom");
lua_pushstring(L, row->custom);
lua_settable(L, -3);

/* We still have table left on top of the Lua stack. */

Also, You could write some kind of C struct iterator or something.

NOTE: if this is for some kind of Lua wrapper - You should ensure standardized way of doing that. In the following example applied @lhf comment about shortening it a bit:

int 
l_row_push(lua_State *l)
{
    lua_createtable(L, 0, 4); /* creates and pushes new table on top of Lua stack */

    lua_pushstring(L, row->name); /* Pushes table value on top of Lua stack */
    lua_setfield(L, -2, "name");  /* table["name"] = row->name. Pops key value */

    lua_pushstring(L, row->date);
    lua_setfield(L, -2, "date");

    lua_pushstring(L, row->ip);
    lua_setfield(L, -2, "ip");

    lua_pushstring(L, row->custom);
    lua_setfield(L, -2, "custom");

    /* Returning one table which is already on top of Lua stack. */
    return 1;
}

EDIT: Fixes usage of lua_setfield() by @lhf note. Thanks!

Share:
18,273
Lucas
Author by

Lucas

Updated on July 18, 2022

Comments

  • Lucas
    Lucas almost 2 years

    I'm running a MySQL query which always returns 4 rows:

    row->name, row->date, row->ip, row->custom

    What I want to achieve is create a simple table basing on the above results so it would look like:

    {
         "name" = result of row->name,
         "date" = result of row->date,
         "ip"   = result of row->ip,
         "custom" = result of row->custom
    }
    

    I have tried multiple possibilities, but the examples posted are really varied and I got a problems making it working.

    My last unsuccessful try:

    lua_createtable(L, 0, 4);
    top = lua_gettop(L);
    lua_pushstring(L, "name");
    lua_pushstring(L, row->name);
    lua_pushstring(L, "date");
    lua_pushnumber(L, row->date);
    lua_pushstring(L, "ip");
    lua_pushstring(L, row->ip);
    lua_pushstring(L, "custom");
    lua_pushstring(L, row->custom);
    lua_settable(L, top);
    
  • Kamiccolo
    Kamiccolo over 10 years
    @Lucas yeah, it might look tricky at the beginning. Overall - it's not that bad at all.
  • Lucas
    Lucas over 10 years
    Can I use the lua_newtable instead of the lua_createtable ?
  • Kamiccolo
    Kamiccolo over 10 years
    @Lucas definitely. lua_createtable() saves some time of increasing memory allocated for the table each time inserting stuff. And recommended to be used. If size of table is not known, You're free to use lua_newtable.
  • Lucas
    Lucas over 10 years
    The code is compiling itself, but in Lua when I do print(variable["name"]); nothing is being printed.
  • Lucas
    Lucas over 10 years
    And yes, I am using a wrapper, did that like on your example so you could know how its looks like: pastebin.com/raw.php?i=WQVugBz7
  • Lucas
    Lucas over 10 years
    Nevermind, return 1 worked for it, just seen that its not going to return 4 tables, lol. Thank you very much!
  • Kamiccolo
    Kamiccolo over 10 years
    @Lucas could You show fuller example of what You're trying to do, please? Are You using lightuserdata to pass values from Lua state machine?
  • lhf
    lhf over 10 years
    lua_setfield receives the key not the value.
  • Kamiccolo
    Kamiccolo over 10 years
    @lhf Fixed. Thank You very much for noticing!