1

如何使用 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].bc[1].d = 1; 我尝试将它一起使用,但它不起作用。错误消息:PANIC:调用 Lua API 时出现未受保护的错误(尝试索引数字值)

在 lua 中 a[1].bc = 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].bc[1].d = 1; 可以做成同样的形式吗?

4

1 回答 1

1

起初您使用lua_pop不正确,主要用途是从堆栈中删除顶部元素的数量。在lua.h #define lua_pop(n) lua_settop(L, -(n)-1),在您的情况下,它可能与您的情况相同lua_settop(L, 1),但如果堆栈中有某些东西(如参数),则可能会导致失败。在您的代码lua_pop中根本不需要,因为您在这一行上的堆栈已经填满了表格,所以它必须是:

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

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

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

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

        lua_setfield(L, -2, "b"); // stack: {1={b={c=49}}}, 2, {b={c=50}}
        lua_settable(L, -3); // stack: {1={b={c=49}}, 2={b={c=50}}}
    }
}
lua_setglobal(L, "a"); // stack is empty, _G.a={ {b={c=49}}, {b={c=50}}}

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

lua_newtable(L);          // stack:...,{}
lua_pushnumber(L, 1);     // stack:...,{},1
lua_newtable(L);          // stack:...,{},1,{}
lua_pushnumber(L, 1);     // stack:...,{},1,{},1
lua_setfield(L, -2, "d"); // stack:...,{},1,{d=1}
lua_settable(L, -3);      //stack:...,{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++) { // adding 4 tables obj_a
  lua_createtable(L, 0, 1); //obj_a
  lua_createtable(L, 4, 0); //obj_c[4]
  for (j = 1; j <= 4; j++) { // adding 4 tables obj_c
    lua_createtable(L, 0, 1); //obj_c
    lua_pushinteger(L, 0); //default d value
    lua_setfield(L, -2, "d"); //{d=0}
    lua_seti(L, -2, j); //add table obj_c to array
  }
  lua_setfield(L, -2, "b"); // {b=obj_c[4]}
  lua_seti(L, -2, i); //add table obj_a to array
}
lua_setglobal(L, "a");
于 2020-11-16T15:40:02.027 回答