等价于使用Lua_newsthread在C++中创建Lua协程

Equivalent of Lua coroutine.create in C++ using lua_newthread

本文关键字:Lua C++ 创建 协程 newsthread 等价于      更新时间:2023-10-16

我有一个回调系统,它可以向C++处理程序添加lua函数,例如在lua中,我可以执行

myCObject:AddCallback(luaFunc)

我也有同样的,用于协同程序

myCObject:AddCallback(coroutine.create(luaFunc))

然后我可以使用

lua_State * pThread = lua_tothread(L, -1);
lua_resume(pThread, 0,0);

在C++中

启动/恢复lua功能。

现在,我不想要求脚本编写人员编写coroutine.create(luaFunc),我只想自动将一个luaFunc"转换"为一个coroutine。当AddCallback被调用时,我在堆栈上有luaFunc,然后我该如何继续?(使用coroutine.create,我已经在堆栈上有了一个线程)

编辑:我正在寻找一个使用C API的解决方案,例如lua_newsthread

这个想法相当简单。首先,创建一个新线程。

lua_State *pThread = lua_newthread(L);

此函数还将该线程推送到L上。下一步是将线程函数放到pThread上。假设此时堆栈上有一个Lua函数,那么下一步就是将该函数转移到pThread堆栈。

有一个函数专门用于在线程之间传递值:lua_xmove。但是,它只传输堆栈的顶部元素。因此,您需要将Lua函数从L堆栈上的位置复制到L堆栈的顶部。然后lua_xmove将其发送到新堆栈。

lua_pushvalue(L, #); //Where # is the index in the stack where the function is.
                     //Remember that lua_newthread pushed a value on the stack, so compensate for that.
lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack.

请记住,lua_xmove会移动值,从而将其从L中删除。因此,lua_pushvalue推送该值,lua_xmove弹出该值。因此,堆栈的顶部再次是由pThread表示的lua_State

之后,将您需要发送的所有参数推送到函数(显然为零),然后恢复它

lua_resume(pThread, 0, 0);

总代码:

lua_State *pThread = lua_newthread(L);
lua_pushvalue(L, #); //Where # is the index in the stack where the function is.
                     //Remember that lua_newthread pushed a value on the stack, so compensate for that.
lua_xmove(L, pThread, 1); //Moves the function to the top of the new stack.
lua_resume(pThread, 0, 0);

Lua线程(无论是在Lua中创建的还是在C API中创建的)都是Lua值,就像表、用户数据、字符串等一样。因此,它会受到垃圾回收。当Lua检测到不再有对该值的引用时,它将被收集。

记住:lua_newthread将线程推送到原始堆栈上。您可以将它复制到注册表中,或者复制到全局环境中,或者将该线程永久驻留在任何位置。简单地保留一个指向它生成的lua_State的指针并不能确保线程保持活动状态。

我已经很久没有做过很多lua的东西了,所以我有点生疏。但是,我认为你想做的是:

  • 提取luaFunc
  • 然后打开coroutine.create功能
  • 然后重新打开luaFunc
  • 并使用lua_pcall在堆栈上获取线程

根据您的评论,您希望使用lua_newthread。我没有任何经验,但我确实找到了这个答案,其中包含一个使用它的示例程序