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

Ste*_*eve 3 c++ lua

我有一个回调系统,它可以将lua函数添加到C++处理程序,例如我可以做的lua

myCObject:AddCallback(luaFunc)
Run Code Online (Sandbox Code Playgroud)

对于协程,我也有相同的

myCObject:AddCallback(coroutine.create(luaFunc))
Run Code Online (Sandbox Code Playgroud)

然后我可以使用

lua_State * pThread = lua_tothread(L, -1);
lua_resume(pThread, 0,0);
Run Code Online (Sandbox Code Playgroud)

在C++中

启动/恢复lua功能.

现在,我不想要脚本编写者写coroutine.create(luaFunc) - 我只是想自动"转换"一个lua func到一个协程.当调用AddCallback时,我在堆栈上有luaFunc - 然后我该如何继续?(使用coroutine.create我已经在堆栈上有一个线程)

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

Nic*_*las 10

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

lua_State *pThread = lua_newthread(L);
Run Code Online (Sandbox Code Playgroud)

此函数也将该线程推送到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.
Run Code Online (Sandbox Code Playgroud)

请记住,lua_xmove 移动值,将其删除L.所以lua_pushvalue推动价值,并lua_xmove弹出它.所以堆栈的顶部再次lua_State表示为pThread.

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

lua_resume(pThread, 0, 0);
Run Code Online (Sandbox Code Playgroud)

总代码:

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);
Run Code Online (Sandbox Code Playgroud)

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

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