2011-06-19 146 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

相关问题