递归pCall函数

时间:2018-09-12 16:26:23

标签: c++ recursion lua

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

我的设置如下。

class LuaObject
{
    public:

    lua_State* m_pLuaState;

    void Execute
    {
        //push processed script
        lua_pushvalue( m_pLuaState , -1 );

        //now run it
        int iStatus = lua_pcall( m_pLuaState, 0, 1, 0 );

        //remove the return value from the stack
        lua_pop( m_pLuaState, 1 );
    }
}

因此,鉴于上述设置。可以先调用LuaObject :: Execute(),然后在内部调用相同的LuaObject :: Execute(),后者将以与先前的pcall相同的lua_State运行lua_pcall。我应该以某种方式确保在每次递归调用之前准备好m_pLuaState吗?  还是应该为每个lua_pcall创建一个新的lua_State?我觉得准备相同的m_pLuaState是正确的方法,但是我该怎么做?也许从处理此脚本时开始将lua_TFunction推送到堆栈上?

1 个答案:

答案 0 :(得分:0)

递归调用应该没有问题,只要您不会在此类调用中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;
}

您遇到的任何错误(无法按预期方式工作,等等)都可能与脚本和背后的逻辑有关,而与调用是递归的无关。