递归 pCall 函数

我遇到了一个情况,在其中一个 lua_pcall 内部有时会递归调用。递归调用不能按预期工作。我认为这是因为第二次调用仍具有先前 lua_pcall 的状态。堆栈仍然可以包含第一个 lua_pcall 的变量,更不用说 lua 在 lua_State 内部使用的所有其他内部变量了。

我的设置如下:

class LuaObject
{
    public:

    lua_State* m_pLuaState;

    void 执行
    {
        //将处理过的脚本推入栈中
        lua_pushvalue( m_pLuaState , -1 );

        //现在运行它
        int iStatus = lua_pcall( m_pLuaState, 0, 1, 0 );

        //从堆栈中弹出返回值
        lua_pop( m_pLuaState, 1 );
    }
}

因此,给定上述设置。可以调用 LuaObject::执行(),然后在内部,它可能调用相同的 LuaObject::执行(),这将使用与先前 pcall 相同的 lua_State 运行 lua_pcall。我应该确保每次递归调用之前都要准备好 m_pLuaState 吗? 还是应该为每个 lua_pcall 创建一个新的 lua_State?我觉得准备相同的 m_pLuaState 是正确的方法,但我该如何做呢?也许将此脚本处理时的 lua_TFunction 推入堆栈中?

点赞
用户5675002
用户5675002

只要你不在这样的调用中使用 yield,递归调用应该没有问题。使用 yield 相当于使用 longjmp,会打断调用链,但这并不适用于常规的 lua_pcall 用法。

尝试运行下面的示例(已在 Lua 5.2 中测试)。它有一个名为 foo 的函数,调用本地函数 bar,后者再次调用 foo,并减小计数器。没有特殊操作需要处理递归调用。

#include <lualib.h>
#include <lauxlib.h>
#include <stdio.h>
#include <stdlib.h>

int bar(lua_State* L)
{
    int num = lua_tointeger(L, 1);
    printf("bar: %d\n", num);
    if(num>0)
    {
        // call foo with decremented iteration count
        lua_getglobal(L, "foo");
        lua_pushinteger(L, num-1);
        lua_pcall(L, 1, 1, 0);
        lua_pop(L, 1);
    }
    return 0;
}

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

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

    luaL_dostring(L, "function foo(x)\n"
                     "  print(\"foo: \"..x)\n"
                     "  bar(x)\n"
                     "end\n");

    // call foo with 7 as iterations count
    lua_getglobal(L, "foo");
    lua_pushinteger(L, 7);
    lua_pcall(L, 1, 1, 0);
    lua_pop(L, 1);

    lua_close(L);

    return 0;
}

无论您的情况(未按预期工作等)是什么,都可能与脚本和背后的逻辑有关,而不是与调用递归有关。

2018-09-12 17:03:56