Lua从Lua到C的嵌套表 [英] Lua nested table from Lua to C

查看:182
本文介绍了Lua从Lua到C的嵌套表的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我非常无法将嵌套的Lua表转换为C json对象.我正在使用LuaTableToJson(请参见下面的代码),其中索引"是要检索的参数索引,而PopOneArg是根据其类型处理值的例程.

I miserably fail to convert nested Lua table into C json object. I'm using LuaTableToJson (see code here after) where "index" is the parameter index to retrieve and PopOneArg the routine to process a value depending on its type.

当有嵌套表时,我想递归地调用LuaTableToJson,但是当index = -1时它不起作用.

When having a nested table I would like to call LuaTableToJson recursively, but with index=-1 it does not work.

问题:能否请人指出工作样本以检索作为从Lua传递给C的自变量嵌套表.或者有人可以解释将嵌套表从Lua传递给C时的堆栈结构.

Question: could please someone point on working sample to retreive nested table passed as argument from Lua to C. Alternatively could someone explain the stack structure when passing nested table from Lua to C.

谢谢

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

Note: for C->Lua I have a solution.

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

推荐答案

对于打包的解决方案,请检查我的代码

For a packaged solution, check my code here

本质上,当分析嵌套表时,应该以负索引进行分析.在这种情况下,lua_next会使相对于您正在跟踪的索引的堆栈混乱,因此您需要减少它.

Essentially, when parsing a nested table, you should be parsing at a negative index. In this case, lua_next will mess up the stack relative to the index you're tracking, so you need to decrement it.

您可以尝试

if (index < 0) index--; // change to -- as in your code

解析表时.它应该可以与您的代码一起使用,但是我不能保证不会缺少另一个问题.

When parsing tables. It should work with your code, but I can't promise there's not another problem I'm missing.

我的代码可以在任何级别的嵌套中正常工作,因此我建议以它为例,并在最终代码发布后作为答案.

My code works for sure to any level of nesting, so I'd recommend following it as an example and posting your final code as an answer once it works.

这篇关于Lua从Lua到C的嵌套表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆