2017-08-15 26 views
1

入れ子になったLuaテーブルをC jsonオブジェクトに変換するのに失敗しました。私はLuaTableToJsonを使用しています(ここでコードを参照してください)。 "index"は検索するパラメータインデックスで、PopOneArgはその型に応じて値を処理するルーチンです。LuaからCへのLuaネストしたテーブル

ネストしたテーブルを持っているとき、私はLuaTableToJsonを再帰的に呼び出すことにしましたが、インデックス= -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; 
} 
+1

'lua_next'、整数キー、' lua_tostring'はうまく混ざりません。[manual](http://www.lua.org/manual/5.2/manual.html#lua_tolstring)とこれを確認してください[SO質問](https://stackoverflow.com/questions/29287988/iterating-over-table-of-tables-with-the-lua-c-api/29288604#29288604) – Adam

+0

「数字」は「99」を超えます長さで?その場合は、より大きな配列を作成します。 – ryyker

+0

コメントが分かりません。 lua_stringは適切に処理するとうまく動作します。 99については、問題との関係を理解し​​ていない。ネストしたテーブルのインポートとはどのような関係ですか? – Fulup

答えて

1

、ネストされたテーブルを解析するとき、あなたは負のインデックスでパースする必要があり、基本的に私のコードhere

をご確認ください。この場合、lua_nextは、トラッキングしているインデックスを基準にしてスタックを台無しにするので、減分する必要があります。

テーブルを解析するときあなたは

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

を試すことができます。それはあなたのコードで動作するはずですが、私には別の問題がないことを約束することはできません。

私のコードはどのレベルの入れ子にも対応していますので、例としてそれをフォローして、答えとして最終コードを投稿することをおすすめします。

+0

実際にコードをチェックしていたのは、(index <0)index--;それが必要でした。ご協力いただきありがとうございます。あなたの命題がなければ、私はそのトリックを見つけられませんでした。私のコードは、github.com/iotbzh/audio-bindings/blob/master/Controller-afb/...からアクセスできます。私が前に投稿したコードから、唯一の変更はlua_next(luaState、index)を使ったループの前のものです。if(index <0)index--;を追加する必要がありました。 - Fulup昨日 – Fulup

関連する問題