Lua嵌套表从Lua到C

我试图将嵌套的Lua表转换为C JSON对象,但鲁LuaTableToJson(参见下面的代码),其中"index"是检索参数索引,PopOneArg是处理值的例程,具体取决于其类型。

当存在嵌套表时,我想递归调用LuaTableToJson,但使用index = -1时不起作用。

问题:请问是否有人能够指出从Lua传递嵌套表到C的工作示例。或者,有人能够解释从Lua传递嵌套表到C时堆栈结构。

谢谢

注意:对于C->Lua,我有一个解决方案。

    STATIC json_object *LuaTableToJson (lua_State* luaState, int index) {
    int idx;

    json_object *tableJ= json_object_new_object();
    const char *key;
    char number[3];
    lua_pushnil(luaState); // 1st key
    for (idx=1; lua_next(luaState, index) != 0; idx++) {

        // uses 'key' (at index -2) and 'value' (at index -1)
        if (lua_type(luaState,-2) == LUA_TSTRING) key= lua_tostring(luaState, -2);
        else {
            snprintf(number, sizeof(number),"%d", idx);
            key=number;
        }
        json_object *argJ= PopOneArg(luaState, -1);
        json_object_object_add(tableJ, key, argJ);
        lua_pop(luaState, 1); // removes 'value'; keeps 'key' for next iteration
    }

    // Query is empty free empty json object
    if (idx == 1) {
        json_object_put(tableJ);
        return NULL;
    }
    return tableJ;
}

STATIC  json_object *PopOneArg (lua_State* luaState, int idx) {
    json_object *value=NULL;

    int luaType = lua_type(luaState, idx);
    switch(luaType)  {
        case LUA_TNUMBER: {
            lua_Number number= lua_tonumber(luaState, idx);;
            int nombre = (int)number; // evil trick to determine wether n fits in an integer. (stolen from ltcl.c)
            if (number == nombre) {
                value= json_object_new_int((int)number);
            } else {
                value= json_object_new_double(number);
            }
            break;
        }
        case LUA_TBOOLEAN:
            value=  json_object_new_boolean(lua_toboolean(luaState, idx));
            break;
        case LUA_TSTRING:
           value=  json_object_new_string(lua_tostring(luaState, idx));
            break;
        case LUA_TTABLE: {
            if (idx > 0) {
                value= LuaTableToJson(luaState, idx);
            } else {
                value= json_object_new_string("UNSUPPORTED_Lua_Nested_Table");
            }
            break;
        }
        case LUA_TNIL:
            value=json_object_new_string("nil") ;
            break;

        default:
            AFB_NOTICE ("PopOneArg: script returned Unknown/Unsupported idx=%d type:%d/%s", idx, luaType, lua_typename(luaState, luaType));
            value=NULL;
    }

    return value;
}

static json_object *LuaPopArgs (lua_State* luaState, int start) {
    json_object *responseJ;

    int stop = lua_gettop(luaState);
    if(stop-start <0) return NULL;

    // start at 2 because we are using a function array lib
    if (start == stop) {
        responseJ=PopOneArg (luaState, start);
    } else {
        // loop on remaining return arguments
        responseJ= json_object_new_array();
        for (int idx=start; idx <= stop; idx++) {
            json_object *argJ=PopOneArg (luaState, idx);
            if (!argJ) goto OnErrorExit;
            json_object_array_add(responseJ, argJ);
       }
    }

    return responseJ;

  OnErrorExit:
    return NULL;
}
点赞
用户5597039
用户5597039

如果需要一种封装好的解决方案,请查看我的代码 here

基本上,在解析嵌套表时,您应该在负索引处进行解析。在这种情况下,lua_next会打乱相对于您正在跟踪的索引的堆栈,因此您需要将其减少。

您可以尝试

if (index<0) index--; //更改为--,与您的代码相同

在解析表时。它应该可以与您的代码一起使用,但我不能保证我没有错过其他问题。

我的代码确保可以处理任何级别的嵌套,因此我建议您以此作为示例,并在其工作时将您的最终代码发布为答案。

2017-08-16 01:10:33