I found an example from our project that does what you want.
typedef int (*getSetFunction) (lua_State*);
typedef struct luaMyValReg {
const char *name;
getSetFunction getter;
getSetFunction setter;
} luaMyValReg;
#define luaL_reg luaL_Reg
typedef struct luaMyTable {
luaL_reg *functions;
luaL_reg *methods;
luaMyValReg *values;
luaMyValReg *arrays;
luaL_reg *array_methods;
} luaMyTable;
static const struct luaMyValReg lib_val[] = {
{ "key1", MyClass::l_getKey1, MyClass::l_setKey1},
...
{NULL, NULL, NULL}
}
These are set into a structure and passed to a function that will set up the userdata.
table.functions = (luaL_reg *) &lib_f;
table.methods = (luaL_reg *) &lib_m;
table.values = (luaMyValReg *) &lib_val;
MyClass::initTable(&table, REGNAME, REGID, ARRAY_REGID);
In that function, there is a bit that creates the metatable, and adds each of the fields in the lib_val array. LGlobalState is the lua_State* pointer.
// Register the functions for the Table
luaL_register(LGlobalState, regname, table->functions);
// Stk: Table
// Create the metatable
luaL_newmetatable(LGlobalState, regid);
// Stk: Table metatable
// Register its methods, leaves it on top of the stack
luaL_register(LGlobalState, NULL, table->methods);
// Stk: Table metatable
// Set the metatable
lua_setmetatable(LGlobalState,-2);
// Stk: Table
// Push metatable
lua_getmetatable(LGlobalState, -1);
// Stk: Table metatable
// Add fields to the metatable
int i = 0;
while (table->values[i].name != NULL)
{
addMetaField(LGlobalState, table->values[i].name, i);
i++;
}
// Stk: Table, metatable
lua_pop(LGlobalState, 2);
// Stk: empty
if (lua_gettop(LGlobalState) > 0)
tngL_error(LGlobalState, "%s inconsistant stack size\n", regname);
Here is the function to add the values.
////////////////////////////////////////////////////////////////////////////////
int LUATask::addMetaField(lua_State *L, const char *pKey, int nIndex)
////////////////////////////////////////////////////////////////////////////////
// Add a field to the metatable. It must already be on the top
// of the stack
{
// Stk: metatable
lua_pushstring(L, pKey);
lua_pushnumber(L, nIndex);
// Stk: metatable, string, number
// Use lua_rawset() instead of lua_settable() to avoid
// the __newindex call
lua_rawset(L, -3);
// Stk: metatable
return 1;
}