【问题标题】:Passing table with subtable to Lua function from C++从 C++ 将带有子表的表传递给 Lua 函数
【发布时间】:2018-12-16 05:42:43
【问题描述】:

我正在尝试将带有子表的表作为 C++ 的参数传递给 Lua 函数。

这是我的代码,它不起作用,但显示了我正在尝试做的事情。

    class DragInfo{
    public:
        std::vector <std::string> files;
        glm::vec2 position;
    };

    //a callback that passes DragInfo to a Lua function as a table which has 2 subtables
    void callDragged(DragInfo &info)
    {
        lua_getglobal(L, "dragged");
        if (!lua_isfunction(L, -1))
        {
            lua_pop(L, 1);
            return;
        }
        lua_newtable(L);
        for (size_t i = 0; i < info.files.size(); ++i)
        {
            lua_pushinteger(L, static_cast<lua_Integer>(i + 1));
            lua_pushstring(L, info.files[i].c_str());
            lua_settable(L, -3);
        }
        lua_pushnumber(L, static_cast<lua_Number>(info.position.x));
        lua_setfield(L, -2, "x");
        lua_pushnumber(L, static_cast<lua_Number>(info.position.y));
        lua_setfield(L, -2, "y");

        if (lua_pcall(L, 1, 0, 0))
            std::cout << "Error : " <<  lua_tostring(L, -1) << std::endl;
    }

例如,在 Lua 中,我希望能够......

function dragged(info)
   for i=1, #info.files do
       print("dragged filename: " .. info.files[i])
   end
   print("dragged position: " .. info.position.x .. " " .. info.position.y)
end

结果可能是这样的

dragged filename: background.jpg
dragged filename: apple.png
dragged position: 425 32

我应该如何更正我的 C++ 函数,使其像示例一样正常工作?

【问题讨论】:

    标签: c++ lua lua-table


    【解决方案1】:

    这很简单。只需创建子表并将其分配给最外层表中的字段。

    如果dragged 不是函数而不是什么都不做,我还建议您引发错误。

    // a callback that passes DragInfo to a Lua function as a table which has 2
    // subtables
    void callDragged(DragInfo &info) {
        lua_getglobal(L, "dragged");
        if (!lua_isfunction(L, -1)) {
            lua_pop(L, 1);
            lua_pushstring(L, "argument is not a function");
            lua_error(L);
            return;
        }
    
        // outermost table
        lua_newtable(L);
    
        // subtable "files"
        lua_newtable(L);
        for (size_t i = 0; i < info.files.size(); ++i) {
            lua_pushinteger(L, i + 1);
            lua_pushstring(L, info.files[i].c_str());
            lua_settable(L, -3);
        }
        lua_setfield(L, -2, "files");
    
        // subtable "position"
        lua_newtable(L);
        lua_pushnumber(L, info.position.x);
        lua_setfield(L, -2, "x");
        lua_pushnumber(L, info.position.y);
        lua_setfield(L, -2, "y");
        lua_setfield(L, -2, "position");
    
        if (lua_pcall(L, 1, 0, 0) != 0) {
            std::cout << "Error : " << lua_tostring(L, -1) << '\n';
            lua_pop(L, 1);
        }
    }
    

    【讨论】:

    • 非常感谢您的回答。我不需要在return 之前将lua_pop(L, 1) 放在if (!lua_isfunction(L, -1)) 中吗?
    • @ZackLee 由于错误结束了程序,它并不重要,但技术上是的。我现在把它放在那里,以防在pcall 中调用该函数。
    • 谢谢!最后一个问题:调用lua_setglobal(L, "name")之后也需要lua_pop(L,1)吗?
    • @ZackLee “从堆栈中弹出一个值并将其设置为全局的新值”lua.org/manual/5.3/manual.html#lua_setglobal
    猜你喜欢
    • 2018-12-15
    • 1970-01-01
    • 1970-01-01
    • 2010-10-02
    • 1970-01-01
    • 2021-05-01
    • 2012-05-27
    • 1970-01-01
    • 2021-12-22
    相关资源
    最近更新 更多