相当于lua coroutine.create,在C ++中使用lua_newthread

问题描述 投票:3回答:2

我有一个回调系统,该系统可以将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

c++ lua
2个回答
10
投票

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

lua_State *pThread = lua_newthread(L);

此功能还将该线程推入L。下一步是将线程功能添加到pThread。鉴于此时您在堆栈上具有Lua函数,下一步是将该函数转移到pThread堆栈。

[有一个专门用于在线程之间传输值的功能:lua_xmove。但是,它仅传输堆栈的顶部元素。因此,您需要将Lua函数从lua_xmove堆栈上的位置复制到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线程(无论是在Lua还是在C API中创建的)都是Lua值,就像表,用户数据,字符串等一样。因此,它受到垃圾回收的影响。当Lua检测到不再有对该值的引用时,它将被收集。

请记住: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_newthread的指针,即可确保线程保持活动状态。

我很长时间没有做很多lua_State的工作,所以我有点生锈。但是,我认为您想做的是:

    提取lua
  • 然后打开luaFunc功能
  • 然后重新按下coroutine.create
  • 并使用luaFunc将您的线程放到堆栈上。
  • 根据您的评论,您想使用lua_pcall。我没有任何经验,但是我确实找到了lua_newthread,其中包含使用它的示例程序。

  • 2
    投票
    我很长时间没有做很多lua_State的工作,所以我有点生锈。但是,我认为您想做的是:
    © www.soinside.com 2019 - 2024. All rights reserved.