代码之家  ›  专栏  ›  技术社区  ›  sean riley

如何从C中执行Lua表操作?

lua c
  •  2
  • sean riley  · 技术社区  · 16 年前

    我需要在Lua表上执行操作 C 将表视为列表或队列的位置。具体来说,我需要在头部插入一个元素,然后移除头部元素,并移动其他元素以适应新元素。

    这在纯Lua中很简单,我会用 table.insert table.remove . 但在 C ?

    Lua中有函数 C API,如Lua_可设置,但没有 插入表 和桌子。去掉表面的。好像里面有 C 调用的解释器内的函数 tinsert tremove 但它们不是API的一部分。

    我真的需要调用一个Lua函数来实现它吗?

    2 回复  |  直到 9 年前
        1
  •  4
  •   Nick Dandoulakis    16 年前

    我相信你可以重用这些功能

    static int tinsert (lua_State *L)
    static int tremove (lua_State *L)
    

    #define aux_getn(L,n)   (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
    

    在LTablib.c中,它们只依赖Lua的API。

        2
  •  1
  •   Norman Ramsey    16 年前

    代码没有测试,但这里有一个草图。传递表的索引,对于insert函数,还传递要插入的值的索引。对于删除,值被推送到Lua堆栈上。

    #define getn(L,n) (luaL_checktype(L, n, LUA_TTABLE), luaL_getn(L, n))
    
    void insert_at_head (lua_State *L, int tbl_idx, int val_idx) {
      int e;
      /* shift elements right to make room */
      for (e = getn(L, tbl_idx) + 1; e > 1; e--) {
        lua_rawgeti(L, tbl_idx, e-1);
        lua_rawseti(L, tbl_idx, e);
      }
      lua_pushvalue(L, val_idx);
      lua_rawseti(L, tbl_idx, 1);
    }
    
    void remove_from_head_and_push (lua_State *L, int tbl_idx) {
      int e;
      int n = getn(L, tbl_idx);
      if (n == 0)
        return luaL_error("removed from head of empty list");
      lua_rawgeti(L, tbl_idx, 1);  /* push first element */
      /* shift elements left */
      for (e = 2; e < n; e++)
        lua_rawgeti(L, tbl_idx, e);
        lua_rawseti(L, tbl_idx, e-1);
      }
      lua_pushnil(L, val_idx);
      lua_rawseti(L, tbl_idx, n);
    }