使用lua_newthread在C ++中等效Lua coroutine.create

时间:2012-07-08 00:05:50

标签: c++ lua

我有一个回调系统,它可以将lua函数添加到C ++处理程序,例如在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) - 我只想自动将lua函数“转换”为协同程序。当调用AddCallback时,我在堆栈上有luaFunc - 然后我该如何继续? (使用coroutine.create我已经在堆栈上有一个线程)

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

2 个答案:

答案 0 :(得分:9)

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

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弹出它。因此,堆栈的顶部再次是由lua_State表示的pThread

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

lua_resume(pThread, 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);

Lua线程(无论是在Lua中还是在C API中创建)都是Lua值,就像表,userdata,string等一样。因此,它受垃圾回收的影响。当Lua检测到没有更多对该值的引用时,将收集它。

请记住:lua_newthread将线程推送到原始堆栈。您可以将其复制到注册表中,也可以复制到全局环境中,也可以将其复制到该线程永久驻留的位置。只需保持指向它生成的lua_State 的指针就不会确保线程保持活动状态。

答案 1 :(得分:2)

我很长时间没有做过很多lua的事情,所以我有点生疏了。但是,我认为你想要做的是:

  • 提取luaFunc
  • 然后按
  • 上的coroutine.create功能
  • 然后将luaFunc重新打开
  • 并使用lua_pcall将您的主题放在堆栈上。

根据您的评论,您要使用lua_newthread。我没有任何使用经验,但我确实找到this answer,其中包含一个使用它的示例程序。