2011-06-19 162 views
3

編輯: 正如我以前評論,我的問題是我不能創建一個C中使用字符串作爲關鍵的表。我做了一個簡單的測試程序,它證明了我有問題:爲什麼Lua在這段代碼中返回一個空表?

下面是它的C++部分:

#include <lua.hpp> 
#include <String.h> 

BString 
LuaTypeToString(lua_State *L, int index, int type) 
{ 
    BString out; 
    switch (type) 
    { 
     case LUA_TSTRING: 
     { 
      out << "'" << lua_tostring(L, index) << "'"; 
      break; 
     } 
     case LUA_TBOOLEAN: 
     { 
      out << (lua_toboolean(L, index) ? "true" : "false"); 
      break; 
     } 
     case LUA_TNUMBER: 
     { 
      out << (float)lua_tonumber(L, index); 
      break; 
     } 
     default: 
     { 
      out << lua_typename(L, type); 
      break; 
     } 
    } 
    return out; 
} 


void 
DumpLuaTable(lua_State *L, int tableIndex) 
{ 
    lua_pushnil(L); 
    printf("\t{ "); 
    while (lua_next(L, tableIndex) != 0) 
    { 
     BString keyString = lua_tostring(L, -2); 

     BString valueString; 
     int type = lua_type(L, -1); 
     if (type == LUA_TTABLE) 
      DumpLuaTable(L, lua_gettop(L)); 
     else 
      valueString = LuaTypeToString(L, -1, type); 

     printf("%s=%s,", 
      keyString.String(), 
      valueString.String()); 
     lua_pop(L, 1); 

     if (lua_isnumber(L, -1)) 
     { 
      lua_pop(L, 1); 
      break; 
     } 
    } 
    printf(" }"); 
} 


void 
DumpLuaStack(lua_State *L) 
{ 
    printf("DumpLuaStack:\n"); 
    int top = lua_gettop(L); 
    for (int i = 1; i <= top; i++) 
    { 
     int type = lua_type(L, i); 
     if (type == LUA_TTABLE) 
      DumpLuaTable(L, i); 
     else 
      printf("\t%s ", LuaTypeToString(L, i, type).String()); 
    } 
    printf("\n"); 
} 



static 
int 
ReturnTable(lua_State *L) 
{ 
    lua_newtable(L); 
    lua_pushnumber(L, 3.14); 
    lua_pushstring(L, "1"); 
    lua_settable(L, -3); 

    DumpLuaStack(L); 

    return 1; 
} 


int 
main(void) 
{ 
    lua_State *L = luaL_newstate(); 
    luaL_openlibs(L); 

    lua_pushcfunction(L, ReturnTable); 
    lua_setglobal(L, "ReturnTable"); 

    int status = luaL_dofile(L, "luatest.lua"); 
    if (status) 
     printf("Status = %d: %s\n", status, lua_tostring(L, -1)); 

    lua_close(L); 

    return status; 
} 

而且它的Lua的部分:

function DumpTable(table) 
    print("LuaDumpTable") 
    local out = "\t" 
    if #table > 0 then 
     for i, v in ipairs(table) do 
      out = out .. i .. "=" .. v .. " " 
     end 
     print(out) 
    else 
     print("\tEmpty table") 
    end 
end 

value = ReturnTable() 
if (type(value) == "table") then 
    DumpTable(value) 
else 
    print(type(value)) 
end 

代碼因爲它是沒有問題的工作--Lua腳本打印出你所期望的。改變推3.14到堆棧的線,比如lua_pushstring(L, "foo");,我得到的只是Lua端的一個空表。任何想法我在這裏做錯了嗎?

+2

我能想到的唯一的事情是要表明你用它來確定該表是空的Lua代碼。你在這裏展示的所有東西都是正確的 –

+0

您是否看過B Mitch的評論?你有沒有看到他在他的DumpTable版本中沒有使用'#table'?你有沒有看到他是如何不使用'ipairs'並使用'pairs'呢?你爲什麼不這樣做,看看它是如何工作的。 –

回答

5

你沒有正確地檢查表中的Lua:

if #table > 0 then 

#table只是告訴你,在表中的第一個未使用的整數爲0。當你插入到表中的字符串,它不會增加計數,因爲它不是連續數組的一部分,而且您也無法使用ipairs進行處理。只需切換到使用pairs,你應該看到foo

function DumpTable(table) 
    print("LuaDumpTable") 
    local out = "\t" 
    for i, v in pairs(table) do 
     out = out .. i .. "=" .. v .. " " 
    end 
    print(out) 
end 

舊一點,留下作爲一個供參考:

我懷疑這會造成問題,但對於API的Lua中被調用,你通常想從堆棧中彈出輸入。後因此lua_tonumber電話:

int32 value = lua_tonumber(L, 1); 

lua_pop(L, 1); 

rgb_color c = ui_color((color_which)value); 
+0

在等待答案時,我將我正在做的事情分解成快速測試項目。我在返回一個使用字符串鍵的表時遇到問題。我不得不一秒鐘走出門外,但當我回來時我會發布修訂版。 – DarkWyrm

+1

*打額頭*當然!我忘記了#運算符(和lua_objlen)只計算整數索引。我不知道ipairs vs pair的事情,所以非常感謝你的時間和耐心。 :) – DarkWyrm

相關問題