【问题标题】:Is there a lua-c api function which doesn't remove the complete stack?是否有一个不会删除完整堆栈的 lua-c api 函数?
【发布时间】:2019-09-12 20:17:04
【问题描述】:

我的问题是 lua_pcall 清除了堆栈,因为我想在再次调用之前重用堆栈,只需再次进行一次更改。
有没有办法复制完整的堆栈并再次粘贴,甚至可以在不清除堆栈的情况下调用 lua 函数?

卢阿:

function test(a)
    print(a)
end

event.add("test", test)
event.add("test", test)

event.call("test", 42)

C++:

int Func_Event_call(Lua_State* L){

    //Stack: String:Eventname, Arguments...

    std::string name = luaL_checkstring(L, 1);

    ... Get array functions from name

    for(...){

        //load function into stack
        lua_rawgeti(L, LUA_REGISTRYINDEX, functions[c]);
        lua_replace(L, 1);

        //Wanted Stack: Lua_Function, Arguments... <- works for the first function

        //call function
        lua_pcall(L, nummberArgs, 0, 0);

        //stack is now empty because of lua_pcall <- problem
    }

    return 0;
}

【问题讨论】:

  • 嗨!你的解释能更清楚吗?尝试编辑你的帖子并添加一些格式来表达你的观点(你没有使用换行符或不同的句子,这让你的观点很难理解)。 SO见;)
  • 您可能正在寻找的是创建一个可在 Lua 中调用的 C 函数——它们接收当前堆栈,以及其上的函数参数;或者让你的 API 收到一个闭包。那些可以携带自己的状态,因此堆栈是否被清除无关紧要 - 只要您调用相同的 Lua 状态 ofc。
  • @dualed 我更新了代码示例,我遇到了从 lua_pcall 中清除堆栈的问题,我想从 lua 函数中调用多个函数,并且需要一种方法来存储和复制堆栈之前通过 lua_pcall 调用或调用 lua 函数而不重置堆栈。
  • 我可能刚刚意识到你在问什么,并且有一个完全不同的假设 - 如果你认为你的 C++ 代码由于反复推入堆栈而变得笨拙或缓慢,那么你认为错了;此外,pcall 并没有真正从堆栈中清除您的函数参数,将其视为使用它们的函数 - 这就是 Lua C API 的工作原理。不要乱堆...
  • @Marlonie2010 您应该将您的解决方案作为答案发布,而不是将其添加到您的问题中 - 回答您自己的问题本身并没有错

标签: lua luac


【解决方案1】:
    //store stack in Registry
    lua_createtable(L, nummberArgs, nummberArgs);
    lua_insert(L, 1);

    //fill table
    for (int c = 0; c < nummberArgs; c++) {

        lua_pushinteger(L, c);
        lua_insert(L, -2);
        lua_settable(L, 1);

    }

    //store it in Registry and clean up
    int reg_key = luaL_ref(L, LUA_REGISTRYINDEX);
    lua_remove(L, 1);

    ...

    //restore stack from above
    lua_rawgeti(L, LUA_REGISTRYINDEX, reg_key);

    //iterate over the table to get all elements, the key is getting removed by lua_next
    lua_pushnil(L);
    while (lua_next(L, 1) != 0) {
        /* uses 'key' (at index -2) and 'value' (at index -1) */
        /* move 'value'; keeps 'key' for next iteration */
        lua_insert(L, -2);
    }

    //remove table from stack
    lua_remove(L, 1);

我通过使用注册表中的表格解决了这个问题,并将完整的堆栈放入带有数字键的表格中。调用第二部分后,我可以在调用第一部分时返回堆栈,但多次。

【讨论】:

    猜你喜欢
    • 2015-08-06
    • 1970-01-01
    • 1970-01-01
    • 2020-10-15
    • 1970-01-01
    • 1970-01-01
    • 2015-06-17
    • 2010-09-15
    • 2021-05-08
    相关资源
    最近更新 更多