我遇到一种情况,有时可以递归调用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推送到堆栈上?
答案 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;
}
您遇到的任何错误(无法按预期方式工作,等等)都可能与脚本和背后的逻辑有关,而与调用是递归的无关。