Почему Lua возвращает пустую таблицу в этом коде? - PullRequest
3 голосов
/ 19 июня 2011

редактирование: Как я уже говорил, моя проблема в том, что я не могу создать таблицу в C, которая использует строки в качестве ключей. Я сделал быструю тестовую программу, которая демонстрирует мою проблему:

Вот часть 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. Есть идеи, что я тут делаю не так?

1 Ответ

5 голосов
/ 19 июня 2011

Вы неправильно проверяете таблицу в 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...