Lua / C绑定,从lua绑定

时间:2011-09-17 09:05:09

标签: c binding lua

我目前正在构建一个lua事件系统(在lua中),但是我希望能够从C激发事件,我想要将C函数绑定到lua函数,这样C函数就可以触发在lua的事件,我打算使用:

lua_register

功能;但是我似乎找不到像这样绑定我的lua函数的方法,看起来我需要一个lua函数来做同样的事情,但是从lua方面来说,我正在考虑做一些hack,将C函数绑定到lua中,只是调用'lua_register',但这对我来说似乎有些不安全。

那我该怎么做呢?

1 个答案:

答案 0 :(得分:5)

我不完全确定我理解你的要求。所以请允许我解释一下我认为你的问题是什么。

你有一些Lua代码。在那个Lua代码中,你有一个系统。在某个时刻,该系统被给予一个或多个事件。对于给定的每个事件,它调用一些函数或函数,这些函数或函数在给定特定事件时被调用。

因此,该系统有两个基本功能:

EventSystem:RegisterEventHandler(EventName, Func);
EventSystem:FireEvent(EventName, ...);

RegisterEventHandler方法会将给定的Func与给定的EventName相关联,以便稍后调用FireEvent时,如果是Func,则会调用EventName FireEvent Func与注册的lua_register相同。

现在您希望C代码能够将C函数注册为事件处理程序。所以现在是时候讨论在Lua中注册C函数了。

C API调用lua_register实际上是一个宏。它在Lua堆栈上创建一个C函数,然后使用给予lua_register的字符串索引将其放入全局表中。这是两个单独的操作; RegisterEventHandler只是一个方便功能,使它们相同。

你想要的是从C代码调用self,传递C函数作为第三个参数(记住:第一个参数是RegisterEventHandler,因为我用{{:调用了. 1}}而不是"RegisterEventHandler"。如果您使用的是全局事件系统而不是面向对象的系统,则只有两个参数。这需要两件事:

  1. 您必须知道如何从C代码调用Lua函数。
  2. 您必须知道如何将C函数传递给Lua代码。
  3. 第1步:这一切都是通过Lua堆栈完成的(我假设您知道它是如何工作的。如果没有,我有一个pretty substantial answer that explains most everything you might want to know about it)。

    您需要做的第一件事就是将要调用的函数放到堆栈中。为此,您需要获取一个事件系统对象(同样,如果您的事件系统是全局的,只需获取全局表)并将其推送到堆栈中。如何执行此操作取决于事件系统对象的存储位置。据推测,你可以通过全局表格获取它们。

    在堆栈上安装了事件系统之后,您只需使用lua_register字符串对其进行索引,这将返回我们需要的Lua函数。

    接下来,我们将参数从头到尾推送到堆栈。第一个参数是事件系统对象;它可能仍然在堆栈上,所以我们可以复制它。第二个是事件名称,这很容易推动。第三是C函数。这导致我们:

    第2步: lua_pushcclosure无法完成工作。这太沉重了;它将C函数放在全局表中。我们需要它在堆栈上。所以我们必须使用较低级别的函数:lua_pushcfunction。或lua_pcall,如果您不需要升值。

    这些函数采用C函数,将其包装在Lua中,并将其推送到Lua堆栈。

    现在3个参数在堆栈上,我们可以通过调用{{1}}来调用事件注册函数。或者你最喜欢的Lua函数调用函数;但是你希望这样做。 Lua将使用3个参数和函数本身,以便它们不再在堆栈中。

    由于事件注册函数可能不会返回值,因此堆栈将在我们将函数放入堆栈之前(但不是在我们启动之前),具体取决于在获取函数时执行了多少清理)。

    在此之后,您的C函数将在该事件名称的事件处理程序中注册。