我目前正在构建一个lua事件系统(在lua中),但是我也希望能够从C中激发事件,我想将C函数绑定到lua函数,这样C函数就可以在lua中激发事件,我计划使用:
lua_register函数;但是我似乎找不到像这样绑定lua函数的方法,似乎我需要一个做同样事情的lua函数,但在lua方面,我正在考虑做一些修改,通过将一个C函数绑定到lua中,简单地调用'lua_register',但这对我来说似乎有点不安全。
那么我应该怎么做呢?
发布于 2011-09-17 17:53:21
我不太清楚你要的是什么。所以请允许我解释一下我认为你的问题是什么。
你有一些Lua代码。在Lua代码中,您有一个系统。在某些情况下,这个系统会给出一个或多个事件。对于给定的每个事件,它都会调用一些函数,这些函数被注册为在给定特定事件时被调用。
所以,这个系统有两个基本功能:
EventSystem:RegisterEventHandler(EventName, Func);
EventSystem:FireEvent(EventName, ...);RegisterEventHandler方法将给定的Func与给定的EventName相关联,这样当稍后调用FireEvent时,如果提供给Func的EventName与Func注册的EventName相同,则将调用Func。
现在,您希望C代码能够将C函数注册为事件处理程序。现在是时候讨论一下如何在Lua中注册C函数了。
C API调用lua_register实际上是一个宏。它在Lua堆栈上创建一个C函数,然后使用提供给lua_register的字符串索引将其放入全局表中。这是两个独立的操作;lua_register只是一个方便的函数,使它们相同。
您想要的是从C代码调用RegisterEventHandler,将C函数作为第三个参数传递(记住:第一个参数是self,因为我使用:而不是.调用RegisterEventHandler。如果你使用的是全局事件系统而不是面向对象的事件系统,那么你只有两个参数)。这需要两件事:
步骤1:这一切都是通过Lua堆栈完成的(我假设您知道它是如何工作的。如果没有,我有一个pretty substantial answer that explains most everything you might want to know about it)。
你需要做的第一件事就是把你想要调用的函数放到堆栈上。为此,您需要获取一个事件系统对象(同样,如果您的事件系统是全局的,则只需获取全局表)并将其推送到堆栈上。如何做到这一点取决于您的事件系统对象的存储位置。大概您可以通过全局表获取它们。
一旦你有了堆栈上的事件系统,你只需要用"RegisterEventHandler"字符串来索引它,它将返回我们需要的Lua函数。
接下来,我们从第一个到最后一个将参数推送到堆栈上。第一个参数是事件系统对象;它可能还在堆栈中,所以我们可以复制它。第二个是事件名称,这很容易推送。第三个是C函数。这就引出了以下问题:
第2步: lua_register不会完成工作。它太重了;它把C函数放在了全局表中。我们需要把它放在堆栈上。因此,我们必须使用一个较低级别的函数:lua_pushcclosure。或者lua_pushcfunction,如果你不需要upvalue的话。
这些函数接受一个C函数,将其包装在Lua中,并将其推送到Lua堆栈上。
现在3个参数都在堆栈上了,我们可以通过调用lua_pcall来调用事件注册函数。或者你最喜欢的Lua函数调用函数;不管你想怎么做。Lua将消耗3个参数和函数本身,因此它们不再位于堆栈中。
由于事件注册函数可能不返回值,因此堆栈将位于我们将函数放到堆栈之前的位置(但不是在我们开始之前,这取决于在获取函数时进行了多少清理)。
在此之后,您的C函数将使用该事件名称的事件处理程序进行注册。
https://stackoverflow.com/questions/7453688
复制相似问题