3

我有一个回调系统,它可以将 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 func“转换”为协程。当 AddCallback 被调用时,我在堆栈上有 luaFunc - 然后我该如何继续?(使用 coroutine.create 我已经在堆栈上有一个线程)

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

4

2 回答 2

10

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

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, 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它生成的指针并不能确保线程保持活动状态。

于 2012-07-08T17:48:13.400 回答
2

lua好久没做太多东西了,所以有点生疏了。但是,我认为你想要做的是:

  • 提取luaFunc
  • 然后推coroutine.create功能
  • 然后推luaFunc
  • 并用于lua_pcall将您的线程放在堆栈上。

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

于 2012-07-08T00:17:29.853 回答