2012-12-20 218 views
2

我的問題是無可否認與此類似: How to create nested Lua tables using the C API返回從C多維數組到Lua

我想我明白了答案,但我仍然有問題。我想要返回的對象數組。

 const char * pushlist[] = { 
       "status", "cmdsequence", "timestamp", "gain", 
     }; 
     int nItems = sizeof(pushlist)/sizeof(char *); 
     int iDepth = -(1 + nItems); 

     // // 
     // What we want to do is essentially push an array of tables. 
     // The tables have keys (see pushlist above) and values. 
     // The array is indexed by integers from 1 through N. 
     // 
     lua_newtable(L); 
     for(Json::Value::UInt i = 0; i != totFrames; i++) 
     { 
      lua_pushnumber(L, i + 1); // push the array index 
      lua_newtable(L); 

      Json::Value frame = params["frameinfo"][i]; 

      // now push the table which will be at array index (i + 1) 
      for(int n = 0; n < nItems; n++) 
      { 
       lua_pushstring(L, pushlist[n]);     // push key 
       lua_pushnumber(L, frame[pushlist[n]].asUInt()); // push value 
      } 
      lua_settable(L, iDepth); 
      lua_settable(L, -3); // (note 1) error here 
     } 
     lua_settable(L, iDepth); // (note 2) not clear on the need for this 
     lua_settable(L, -3); 
     lua_setglobal(L, "framedata"); 

所以在Lua我想看:
[0] = {[ 「狀態」] = 1,[ 「cmdsequence」] = 2,[ 「時間戳」] = 3,[ 「增益」 ] = 4}
...
[totFrames-1] = {[「status」] = 5,[「cmdsequence」] = 6,[「timestamp」] = 7,[「gain」] = 8}

我不清楚在注2中2 lua_settable是什麼,但我上面鏈接的答案表明它們是需要的。

lua_settable(L,-3)(注1)出錯。我在C++中這樣做,所以我把這段代碼括在try/catch中。當它第一次達到可設定的水平時,它會抓住我的抓地力。我想我已經損壞了堆棧,但我沒有看到它。


謝謝@Omri Barel的出色答案。我仍然不清楚內部'for'循環後要做什麼。

我現在有這樣的: 常量字符* pushlist [] = { 「狀態」, 「cmdsequence」, 「時間戳」, 「增益」, }; int nItems = sizeof(pushlist)/ sizeof(char *);

 // // 
     // What we want to do is essentially push an array of tables. 
     // The tables have keys (see pushlist above) and values. 
     // The array is indexed by integers from 1 through N. 
     // 
     lua_newtable(L); 
     for(Json::Value::UInt i = 0; i != totFrames; i++) 
     { 
      lua_pushnumber(L, i + 1); // push the array index 
      lua_newtable(L); 

      Json::Value frame = params["frameinfo"][i]; 

      // now push the table which will be at array index (i + 1) 
      for(int n = 0; n < nItems; n++) 
      { 
       lua_pushnumber(L, frame[pushlist[n]].asDouble()); // push value 
       lua_setfield(L, -2, pushlist[n]); 
      } 
      lua_settable(L, -3); // (note 1) error here 
     } 
     //lua_settable(L, -3);  <<-- not certain that this is required 
     lua_setglobal(L, "framedata"); 

我不再炸燬,但我的Lua失敗(沒有錯誤信息,它只是退出)。我懷疑我沒有損壞堆棧,但不知何故,我沒有正確完成這張表,所以我的迴歸很困惑。

我在該數組之前將其他幾個返回值推入到Lua堆棧中,然後在該數組之後再添加一個。

我的Lua調用是這樣的:

 param1,param2,framedata,Err = CCall.ReadFromC(arg, arg); 

我終於有了這個工作。它需要進一步測試,但到目前爲止似乎是正確的。再次感謝@Omri Barel。這是我已經結束的代碼片段。

 const char * pushlist[] = { 
       "status", "cmdsequence", "timestamp", "gain", 
     }; 
     int nItems = sizeof(pushlist)/sizeof(char *); 

     // // 
     // What we want to do is essentially push an array of tables. 
     // The tables have keys (see pushlist above) and values. 
     // The array is indexed by integers from 1 through N. 
     // 
     lua_newtable(L); 
     for(Json::Value::UInt i = 0; i != totFrames; i++) 
     { 
      Json::Value frame = params["frameinfo"][i]; 

      // now push the table which will be at array index (i + 1) 
      lua_newtable(L); 
      for(int n = 0; n < nItems; n++) 
      { 
       const char * itemName = pushlist[n]; 
       if(frame[itemName].isNull()) continue; 
       lua_pushnumber(L, frame[pushlist[n]].asDouble()); // push value 
       lua_setfield(L, -2, pushlist[n]); 
      } 
      lua_rawseti(L, -2, i + 1); 
     } 
+1

當設置'X [i] = y'用'i'是數字,我建議你使用'lua_rawseti',而不是'lua_pushnumber'其次通過'lua_settable'。 –

回答

6

的問題是,你是推太多的鍵/值對將它們添加到表之前。您應該一次添加一對。

在調試Lua時,您可以做的最好的事情是經常轉儲堆棧的內容,以檢查發生了什麼。 「Programming In Lua」中有一些「堆棧傾銷」代碼(第一版對此足夠好)。

讓我們來看看你的代碼(在幀循環中)。

  1. 您創建一個表。堆棧是:

    ... [表]

  2. 你推鍵/值對的:

    ... [表] [關鍵] [值] [關鍵] [值] [鍵值] [值] [鍵值] [值]

  3. 你可以通過iDepth調用settable,這看起來並不正確。在這種情況下,iDepth = -(1+nItems) = -5。但是你推動對,所以它應該是雙倍的。但即使iDepth是正確的,你仍然只調用一次,所以它只從堆棧中刪除一對:

    ... [表] [鍵] [值] [鍵] [值] [鍵值] [值]

  4. 您可以用-3調用settable,但是-3是[value],所以你會得到一個錯誤。

您應該在每個鍵/值對之後調用settable(帶-3)。

而且我也建議使用setfield這有點更清楚。相反的:

lua_pushstring(L, key); 
lua_pushnumber(L, value); 
lua_settable(L, -3); 

您可以使用:

lua_pushnumber(L, value); 
lua_setfield(L, -2, "key"); 
+0

再次感謝@Omri Barel。我現在有這個工作,沒有你就無法完成。我會在上面發佈我的最終代碼。 – halm

+0

@halm很高興我能幫忙;-) –