C++ 如何从另一个lua C函数调用一个lua C函数?

C++ 如何从另一个lua C函数调用一个lua C函数?,c++,recursion,lua,backup,callstack,C++,Recursion,Lua,Backup,Callstack,我正在为我们的应用程序编写一个lua(5.1)扩展,它允许我们的客户在没有我们支持的情况下使用更多屏幕来扩展它 总的来说,这种方法效果很好,在一打包装纸的帮助下,甚至非常舒适,但现在我遇到了以下情况: 我有两个用户数据对象,一个对象计时器和一个对象窗口。 用户可以通过简单地在Timer和OnSizeChanged上定义他们的成员来“附加”事件 这仍然非常有效: mainLoop(C++)->检查所有计时器(C++)->脚本对象是否已连接?(C++),然后: 因此,在下面的场景中,一切都很好(在启

我正在为我们的应用程序编写一个lua(5.1)扩展,它允许我们的客户在没有我们支持的情况下使用更多屏幕来扩展它

总的来说,这种方法效果很好,在一打包装纸的帮助下,甚至非常舒适,但现在我遇到了以下情况:

我有两个用户数据对象,一个对象计时器和一个对象窗口。 用户可以通过简单地在Timer和OnSizeChanged上定义他们的成员来“附加”事件

这仍然非常有效: mainLoop(C++)->检查所有计时器(C++)->脚本对象是否已连接?(C++),然后:

因此,在下面的场景中,一切都很好(在启动调用之前和之后,堆栈绝对为0):

但是,如果lua脚本如下所示:

timer = timer.new()
window = window.new()

function OnTimer(Self)
   window:SetSize(323.5,234.5)   
end

function OnSizeChanged(Self,NewWidth,NewHeight)
Log("Sized changed")
end

timer.OnTimer = OnTimer
window.OnSizeChanged = OnSizeChanged

C++中的调用堆栈将是:

timer::HandleTimer (C++) -> 
push "OnTimer"  function ->
push timer ud -> 
pcall (L,1) -> .. (Lua) 
static int luaChangeSize(lua_State *L) (back to C++) ->
Window::SetSize -> 
The window sees "oooooooh, an event handler has been assigned" -> 
push "OnSizeChanged" function, window ud, x, y -> 
pcall(L,3,0,0) -> .. (Lua) -> 
int luaLog(lua_state* L) (back to C++ again)
当然,在调用OnSizeChanged时,堆栈仍然包含上一个luaChangeSize回调的内容,并且不是空的

我想我可以通过在调用Window::SetSize之前弹出所有luaChangeSize参数并在之后恢复它们来简单地清理堆栈,但这不起作用。根据调用堆栈的星座,结果是有点随机的,从“不能调用数字”到再次随机调用堆栈上的前一个函数。(在所有调用之前和之后,gettop绝对为0)

<> >:我如何备份当前堆栈并在以后恢复它,因为Lua本身在C++ +Lua>C++的星座中?
非常感谢。

备份和恢复堆栈的概念似乎是错误的。你不能让堆栈保持原样,让新的调用在现有堆栈上工作吗。确保所有内容都使用相对顶部索引而不是绝对索引访问堆栈上的项目。

感谢您的快速响应,是的,我也考虑过这个回退解决方案,通过将某种StackOffset变量附加到我们自己的脚本实例对象,就可以使用它来获取“真实”参数计数,如argumentCount=StackOffset-lua_gettop(L)。问题是,所有非我们编写的扩展(如luasocket)仍然依赖gettop来验证参数计数将无法工作。只是想知道是否有一种“干净”的方法可以让递归c调用像从lua脚本调用一样运行。
timer = timer.new()
window = window.new()

function OnTimer(Self)
   window:SetSize(323.5,234.5)   
end

function OnSizeChanged(Self,NewWidth,NewHeight)
Log("Sized changed")
end

timer.OnTimer = OnTimer
window.OnSizeChanged = OnSizeChanged
timer::HandleTimer (C++) -> 
push "OnTimer"  function ->
push timer ud -> 
pcall (L,1) -> .. (Lua) 
static int luaChangeSize(lua_State *L) (back to C++) ->
Window::SetSize -> 
The window sees "oooooooh, an event handler has been assigned" -> 
push "OnSizeChanged" function, window ud, x, y -> 
pcall(L,3,0,0) -> .. (Lua) -> 
int luaLog(lua_state* L) (back to C++ again)