【问题标题】:Lua coroutine error: tempt to yield across metamethod/C-call boundaryLua协程错误:试图跨越元方法/C调用边界
【发布时间】:2014-02-18 22:47:20
【问题描述】:

我正在使用一个允许您在 Lua 中编程的游戏引擎。游戏引擎命令位于从 C 创建的 DLL 中。有一个用 C 创建的 exe 调用 Lua 文件。这个 Lua 文件是你放置所有游戏代码的地方,包括主循环。 exe没有来回切换,但您可以从DLL调用函数。

所以在主循环之前,我创建了一个函数,我将从中创建一个协程。这个函数迭代一个相当大的表,所以每 n 次迭代我产生。这个函数有一个无限的while循环,因为我需要这些东西来运行主游戏循环的每个循环,但如果它在多个循环之间分割就可以了。

然后我用这个函数作为参数创建一个协程。然后在主游戏循环中恢复这个协程。

当我运行我的代码时,我得到了错误:tempt to yield across metamethod/C-call boundary

我在网上阅读了一些东西,但并没有真正理解这里的问题。一旦 exe 调用 Lua 文件,在 Lua 文件完成之前它根本不会返回到 exe,而且由于我在 Lua 文件中有我的主循环,它在我的测试用例中永远不会完成。

那我有什么选择呢?

【问题讨论】:

    标签: lua


    【解决方案1】:

    错误告诉您,您正试图从 Lua 代码中让出,其中在执行让出的 Lua 代码和恢复协程的 Lua 代码之间存在一些 C 函数。要解决这个错误,你必须做的是从 Lua 调用一些 C 函数,它回调 Lua 代码,然后调用 coroutine.yield()

    你不能那样做。相反,您必须重组代码以避免这种情况。由于您没有提供任何代码,因此没有太多可建议的。

    【讨论】:

      【解决方案2】:

      如果您无法更改代码以避免 C/元方法边界,您可以做几件事:

      • 如果您使用的是标准 Lua,并且正在自己编译,请尝试使用 Coco — True C Coroutines for Lua 对其进行修补。

        真正的 C 协程语义意味着您可以跨 C 调用边界从协程产生并恢复到它。

      • 尝试使用LuaJIT 而不是标准的 Lua 解释器。它使用fully resumable VM 表示边界不是问题。

      • 尝试使用Lua 5.2。它具有yieldable pcall and metamethods,这意味着它可以处理您的问题。但是,Lua 5.1 和 Lua 5.2 之间存在一些变化和不兼容。

      【讨论】:

      • 我使用的游戏库确实使用了 LuaJIT!所以我觉得这很有趣,我得到了错误然后给出了你的评论。
      • 你使用的是哪个 LuaJIT 版本?
      • 游戏引擎使用LuaJIT 1.1.6
      • 那么this answer 可能适用于您。使用lua_newcthread() 而不是lua_newthread()。或者使用 LuaJIT 2,但我不确定它是否已准备好生产。
      • 这似乎适用于 C 代码。游戏引擎完成了所有这些,所以我无权访问它:( 我会看看我是否可以说服创作者做出这个改变。谢谢。
      猜你喜欢
      • 2021-04-16
      • 1970-01-01
      • 2015-09-09
      • 2021-09-06
      • 2015-07-18
      • 1970-01-01
      • 2013-07-13
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多