I'm writing C code to check and modify struct members in lua, I'm using metatables
It works for simple definitions, but in array I couldn't make it work, I have the following code
struct pinfo {
int time;
bool hide_name;
int type_info[10];
};
struct mystruct {
int id;
int value;
int option[20];
struct pinfo pf[5];
....
};
int Get_mystruct(lua_State *L) {
struct mystruct *ms = (struct mystruct*)lua_touserdata(L, 1);
lua_pushlightuserdata(L, ms);
luaL_getmetatable(L, "mystruct");
lua_setmetatable(L, -2);
return 1;
}
int mystruct_index(lua_State *L) {
struct mystruct *ms = (struct mystruct*)lua_touserdata(L, 1);
const char *field = lua_tostring(L, 2);
if (strcmp(field, "id") == 0) {
lua_pushinteger(L, ms->id);
}
else if (strcmp(field, "value") == 0) {
lua_pushinteger(L, ms->value);
}
else if (strcmp(field, "option") == 0) {
lua_pushinteger(L, ms->option[lua_tointeger(L, 3)]);
}
else {
lua_pushnil(L);
}
return 1;
}
int mystruct_newindex(lua_State *L) {
struct mystruct *ms = (struct mystruct*)lua_touserdata(L, 1);
const char *field = lua_tostring(L, 2);
int value = (int)lua_tointeger(L, 3);
if (strcmp(field, "id") == 0) {
ms->id = value;
}
else if (strcmp(field, "value") == 0) {
ms->value = value;
}
else if (strcmp(field, "option") == 0) {
ms->option[lua_tointeger(L, 3)] = (int)lua_tointeger(L, 4);
} else {
lua_pushnil(L);
}
return 0;
}
void mystruct_create(lua_State *L) {
luaL_Reg mystructData[] = {
{ "GetMyStruct", Get_mystruct},
{ "__index", mystruct_index},
{ "__newindex", mystruct_newindex},
{NULL, NULL}
};
luaL_newmetatable(L, "mystruct");
luaL_setfuncs(L, mystructData, 0);
lua_setfield(L, -2, "MyStructLua");
}
In lua I use it as follows
local ms = MyStructLua.GetMyStruct(my_ptr)
print(ms.id) // Returns 0, not defined
ms.id = 1000
print(ms.id) // Returns 1000, has been defined
Now when I go to define the array a problem occurs when I try for example
for o = 0, 19 do
mp.option[o] = 1
end
When I go to set the value I get the error bad argument #3 to 'index' (number expected, got no value)
I would like to know how I can work with simple and complex arrays in this metatable, I have struct which is a member array of mystruct how can I also add it to _newindex and _index
mp.option[o] = ...is two, separate index operations ([new]indexoin the result of indexing'option'inmp). The second section of this answer describes the behaviour of nested indexing (although the context of that question is very different). You need the result of indexing'option'in the first table to return a different table (a proxy) that has its own__newindexmetamethod, and then perform the assignment (get the userdata via a separate reference / upvalue).#includedirectives, amainfunction, and enough driving code to create a working environment that can be modified with an example (and preferably hard-code your Lua code - i.e., useluaL_dostring).c_array[lua_tointeger(L, n)]is an invitation for undefined behaviour (when the given index is outside the bounds of your array).