below is the lua table i need to read from C:
listen = {
{ port = 1234, address = "192.168.1.1", userdata = "liunx" },
{ port = 1235, address = "192.168.1.2", userdata = "liunx1" },
{ port = 1236, address = "192.168.1.3", userdata = "liunx2" }
}
below is the c code:
#include <lua.h> /* Always include this when calling Lua */
#include <lauxlib.h> /* Always include this when calling Lua */
#include <lualib.h> /* Prototype for luaL_openlibs(), */
/* always include this when calling Lua */
#include <stdlib.h> /* For function exit() */
#include <stdio.h> /* For input/output */
void bail(lua_State *L, char *msg){
fprintf(stderr, "\nFATAL ERROR:\n %s: %s\n\n",
msg, lua_tostring(L, -1));
exit(1);
}
int main(void)
{
lua_State *L;
L = luaL_newstate(); /* Create Lua state variable */
luaL_openlibs(L); /* Load Lua libraries */
if (luaL_loadfile(L, "cfg.lua"))
bail(L, "luaL_loadfile() failed");
if (lua_pcall(L, 0, 0, 0))
bail(L, "lua_pcall() failed");
// how to read???
lua_getglobal(L, "listen");
lua_close(L);
return 0;
}
I want to travel this table which may contain a few number of data in while loop, but really do not know how to do it, so any tips?
Thanks very much for your tips!Below are the worked code:
#include <lua.h> /* Always include this when calling Lua */
#include <lauxlib.h> /* Always include this when calling Lua */
#include <lualib.h> /* Prototype for luaL_openlibs(), */
/* always include this when calling Lua */
#include <stdlib.h> /* For function exit() */
#include <stdio.h> /* For input/output */
void bail(lua_State *L, char *msg)
{
fprintf(stderr, "\nFATAL ERROR:\n %s: %s\n\n",
msg, lua_tostring(L, -1));
exit(1);
}
int main(void)
{
lua_State *L;
static struct {
const char * name;
int type;
} fields[] = {
{"port", LUA_TNUMBER},
{"address", LUA_TSTRING},
{"userdata", LUA_TSTRING},
{NULL, 0}
};
L = luaL_newstate(); /* Create Lua state variable */
luaL_openlibs(L); /* Load Lua libraries */
if (luaL_loadfile(L, "cfg.lua"))
bail(L, "luaL_loadfile() failed");
if (lua_pcall(L, 0, 0, 0))
bail(L, "lua_pcall() failed");
lua_getglobal(L, "listen");
luaL_checktype(L, -1, LUA_TTABLE);
int i;
for (i = 1; ; i++) {
lua_rawgeti(L, -1, i);
if (lua_isnil(L, -1)) {
lua_pop(L, 1);
break;
}
// an element of the 'listen' table should now be at the top of the stack
luaL_checktype(L, -1, LUA_TTABLE);
// read the content of that element
int field_index;
for (field_index = 0; (fields[field_index].name != NULL
&& fields[field_index].name != NULL); field_index++) {
lua_getfield(L, -1, fields[field_index].name);
luaL_checktype(L, -1, fields[field_index].type);
// you should probably use a function pointer in the fields table.
// I am using a simple switch/case here
switch(field_index) {
case 0:
printf("port: %d\n", (int)lua_tonumber(L, -1));
// do what you want with port
break;
case 1:
printf("address: %s\n", lua_tostring(L, -1));
break;
case 2:
// handle userdata
printf("userdata: %s\n", lua_tostring(L, -1));
break;
}
// remove the field value from the top of the stack
lua_pop(L, 1);
}
// remove the element of the 'listen' table from the top of the stack.
lua_pop(L, 1);
}
lua_close(L);
return 0;
}
You are not too far. The key here is to understand how the Lua API use the stack for everything.
Here is an untested code sample which should get you going:
// this will be used to validate our table
static struct {
const char * name;
int type;
} fields[] = {
{"port", LUA_TNUMBER},
{"address", LUA_TSTRING},
{"userdata", LUA_TSTRING},
NULL
};
lua_getglobal(L, "listen");
// the 'listen' table should be at the top of the stack
luaL_checktype(L, -1, LUA_TTABLE);
// iterate the listen table
int i;
for (i = 1; ; i++) {
lua_rawgeti(L, -1, i);
// when you get nil, you're done
if (lua_isnil(L, -1)) {
lua_pop(L,1);
break;
}
// an element of the 'listen' table should now be at the top of the stack
luaL_checktype(L, -1, LUA_TTABLE);
// read the content of that element
int field_index;
for (field_index = 0; fields[field_index] != NULL; field_index++) {
lua_getfield(L, -1, fields[field_index].name);
luaL_checktype(L, -1, fields[field_index].type);
// you should probably use a function pointer in the fields table.
// I am using a simple switch/case here
switch(field_index) {
case 0:
port = lua_tonumber(L, -1);
// do what you want with port
break;
case 1:
address = lua_tostring(L, -1);
break;
case 2:
// handle userdata
break;
}
// remove the field value from the top of the stack
lua_pop(L, 1);
}
// remove the element of the 'listen' table from the top of the stack.
lua_pop(L, 1);
}
I suggest you use those documentations: Lua API table Lua API ref
来源:https://stackoverflow.com/questions/27037854/lua-c-read-nested-tables