Sim, existe uma forma mais eficiente de transformar uma estrutura complexa como BIG_STRUCT em uma tabela Lua, sem ter que fazer lua_push* e lua_setfield para cada campo individualmente: usando userdata com metatables, ou serialização automática via bindings como Lua C API + introspecção ou bibliotecas externas.
Aqui estão três abordagens alternativas, dependendo do seu objetivo:
---
1. Criar um userdata e expor via metatable (acesso em Lua como se fosse tabela)
Você pode empacotar o BIG_STRUCT como um userdata e definir uma metatable com os métodos __index e __newindex que acessam os campos da estrutura dinamicamente:
BIG_STRUCT* lua_pushBIG_STRUCT(lua_State* L, BIG_STRUCT* data) {
BIG_STRUCT* udata = (BIG_STRUCT*)lua_newuserdata(L, sizeof(BIG_STRUCT));
memcpy(udata, data, sizeof(BIG_STRUCT));
luaL_getmetatable(L, "BIG_STRUCT_MT");
lua_setmetatable(L, -2);
return udata;
}
Depois, você cria uma metatable:
int big_struct_index(lua_State* L) {
BIG_STRUCT* data = (BIG_STRUCT*)luaL_checkudata(L, 1, "BIG_STRUCT_MT");
const char* key = luaL_checkstring(L, 2);
if (strcmp(key, "field_1") == 0) {
lua_pushstring(L, &data->struct_1.field_1);
return 1;
}
// etc...
return 0;
}
void register_big_struct(lua_State* L) {
luaL_newmetatable(L, "BIG_STRUCT_MT");
lua_pushcfunction(L, big_struct_index);
lua_setfield(L, -2, "__index");
lua_pop(L, 1); // remove metatable
}
Vantagem: Você encapsula tudo e evita vários lua_push*.
---
2. Serialização automática com uma biblioteca como luaL_pack ou SWIG/sol2/LuaBridge
Com bibliotecas externas, você pode automatizar a conversão de structs em tabelas sem escrever manualmente cada lua_push*. Exemplos:
SWIG: Gera bindings automáticos entre C/C++ e Lua.
sol2 (C++): Permite acessar structs diretamente como tabelas em Lua.
LuaBridge (C++): Similar ao sol2.
---
3. Geração automática de tabela Lua com introspecção e lua_newtable
Se quiser continuar com a tabela, mas automatizar o processo, pode fazer uma função que percorra os campos da BIG_STRUCT usando macros ou metaprogramação (em C++ é mais fácil) para fazer um dump de toda estrutura em uma tabela Lua:
void push_BIG_STRUCT_as_table(lua_State* L, BIG_STRUCT* data) {
lua_newtable(L);
// struct_1
lua_pushstring(L, "struct_1");
lua_newtable(L);
lua_pushstring(L, "field_1");
lua_pushlstring(L, &data->struct_1.field_1, 1);
lua_settable(L, -3);
// etc...
lua_settable(L, -3);
// struct_N
lua_pushstring(L, "struct_N");
lua_newtable(L);
lua_pushstring(L, "field_N");
lua_pushinteger(L, data->struct_N.field_N);
lua_settable(L, -3);
lua_settable(L, -3);
}
Você ainda precisa escrever campo a campo, mas pode automatizar isso com macros.