如何使用 Lua C API 在 C 语言中创建结构体

如何使用 Lua c api 创建以下 C 语言结构体?

typedef struct _c{
    int d;
} obj_c;
typedef struct _b{
    obj_c c[4];
}obj_b;
typedef struct _a{
    obj_b b;
}obj_a;
obj_a a[4];

lua 中的上述结构 a[1].b.c[1].d = 1; 我尝试使用它,但它不起作用。 出错信息: PANIC: unprotected error in call to Lua API (attempt to index a number value)

在 lua 中 a[1].b.c = 1; 为了像这样使用,我编写了以下代码。 这个代码工作得很正常。

lua_createtable(L, 2, 0); // stack: {} : -1
{
    lua_pushnumber(L, 1); // stack: {}, 1 : -2
    {
        lua_newtable(L); // stack: {}, 1, {} : -3

        lua_createtable(L, 0, 1); // stack: {}, 1, {}, {} : -4
        lua_pushnumber(L, 49);
        lua_setfield(L, -2, "c");

        lua_setfield(L, -2, "b");
        lua_settable(L, -3);
    }
    lua_pushnumber(L, 2); // stack: {}, 2 : -2
    {
        lua_newtable(L); // stack: {}, 2, {} : -3

        lua_createtable(L, 0, 1); // stack: {}, 2, {}, {} : -4
        lua_pushstring(L, 50);
        lua_setfield(L, -2, "c");

        lua_setfield(L, -2, "b");
        lua_settable(L, -3);
    }
}
lua_pop(L, -2);
lua_setglobal(L, "a");

我该怎么做 a[1].b.c[1].d = 1; 是否可以以同样的形式制作?

点赞
用户12918181
用户12918181

首先您没有正确使用 lua_pop,其主要用途是从堆栈顶部删除指定数量的元素。在 lua.h#define lua_pop(n) lua_settop(L, -(n)-1),在您的例子中它将与 lua_settop(L, 1) 相同,但如果堆栈中有其他元素(如参数),它可能导致失败。在您的代码中,lua_pop 根本不需要,因为在此行上您的堆栈已经填充了表格,所以它必须是:

lua_createtable(L, 2, 0); // 堆栈:{}
{
    lua_pushnumber(L, 1); // 堆栈:{},1
    {
        lua_newtable(L); // 堆栈:{},1,{}

        lua_createtable(L, 0, 1); // 堆栈:{},1,{},{}
        lua_pushnumber(L, 49);
        lua_setfield(L, -2, "c"); // 堆栈:{},1,{},{c=49}

        lua_setfield(L, -2, "b"); // 堆栈:{},1,{b={c=49}}
        lua_settable(L, -3); // 堆栈:{1 = {b={c=49}}}
    }
    lua_pushnumber(L, 2); // 堆栈:{1 = {b={c=49}}},2
    {
        lua_newtable(L); // 堆栈:{1 = {b={c=49}}},2,{}

        lua_createtable(L, 0, 1); // 堆栈:{1={b={c=49}}},2,{},{}
        lua_pushstring(L, 50);
        lua_setfield(L, -2, "c"); // 堆栈:{1={b={c=49}}},2,{},{c=50}

        lua_setfield(L, -2, "b"); // 堆栈:{1={b={c=49}}},2,{b={c=50}}
        lua_settable(L, -3); // 堆栈:{1={b={c=49}}, 2={b={c=50}}}
    }
}
lua_setglobal(L, "a"); // 堆栈已空,_G.a={ {b={c=49}}, {b={c=50}}}

如果要将字段 c 设置为表格数组,而不是使用 lua_pushunmber(L, 49)lua_pushnumber(L, 50),请将其替换为以下代码:

lua_newtable(L);          // 堆栈:...,{}
lua_pushnumber(L, 1);     // 堆栈:...,{},1
lua_newtable(L);          // 堆栈:...,{},1,{}
lua_pushnumber(L, 1);     // 堆栈:...,{},1,{},1
lua_setfield(L, -2, "d"); // 堆栈:...,{},1,{d=1}
lua_settable(L, -3);      // 堆栈:...,{1={d=1}}

因此,在您的堆栈中,数字将被填充为表格。

要创建类似于 C 中的空结构:

/*typedef struct _c{
    int d;
} obj_c;
typedef struct _b{
    obj_c c[4];
}obj_b;
typedef struct _a{
    obj_b b;
}obj_a;
obj_a a[4];*/

int i,j;
lua_createtable(L, 4, 0); //obj_a[4]
for (i = 1; i <= 4; i++) { //添加 4 个 obj_a 表格
  lua_createtable(L, 0, 1); //obj_a
  lua_createtable(L, 4, 0); //obj_c[4]
  for (j = 1; j <= 4; j++) { //添加 4 个 obj_c 表格
    lua_createtable(L, 0, 1); //obj_c
    lua_pushinteger(L, 0); //默认的 d 值
    lua_setfield(L, -2, "d"); //{d=0}
    lua_seti(L, -2, j); //将 obj_c 表格添加到数组中
  }
  lua_setfield(L, -2, "b"); // {b=obj_c[4]}
  lua_seti(L, -2, i); //将 obj_a 表格添加到数组中
}
lua_setglobal(L, "a");
2020-11-16 15:40:02