How to create the following C language structure using Lua c api?
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];
The above structure in lua a[1].bc[1].d = 1; I try to use it together, but it doesn't work. Error Message: PANIC: unprotected error in call to Lua API (attempt to index a number value)
in lua a[1].bc = 1; To use like this, I wrote the following code. This code works normally.
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");
What do I do a[1].bc[1].d = 1; Can it be made in the same form?
At first you use lua_pop
not correctly, the main usage is to remove number of top elements from stack. In lua.h
#define lua_pop(n) lua_settop(L, -(n)-1)
, in your case it will be the same as lua_settop(L, 1)
in your case it may be OK, but if there is something in stack (like arguments) it may lead to failure. In your code lua_pop
is not needed at all as your stack on this line already filled table, so it must be:
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}}}
If you want to make field c
as array of tables, instead of lua_pushunmber(L, 49)
and lua_pushnumber(L, 50)
, replace with following code:
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}}
So in your stack instead of number will be filled table.
To create empty structure like in 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");
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.