【问题标题】:lua c read nested tableslua c读取嵌套表
【发布时间】:2015-01-18 05:04:23
【问题描述】:

下面是我需要从 C 读取的 lua 表:

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" }
}

下面是c代码:

#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;
}

我想在while循环中遍历这个可能包含少量数据的表,但真的不知道该怎么做,有什么技巧吗?

非常感谢您的提示!以下是工作代码:

#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;
}

【问题讨论】:

    标签: c linux lua lua-table lua-api


    【解决方案1】:

    你还不算太远。这里的关键是了解 Lua API 如何将堆栈用于所有事情。

    这是一个未经测试的代码示例,应该可以帮助您:

    // 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);
    }
    

    我建议你使用这些文档:Lua API tableLua API ref

    【讨论】:

      猜你喜欢
      • 2013-06-03
      • 2021-10-09
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      • 2014-01-23
      • 2015-09-02
      • 2014-09-23
      • 1970-01-01
      相关资源
      最近更新 更多