I'm currently building a lua event system (in lua), however I want to be ab开发者_开发技巧le to fire events from C too, I was wanting to bind a C function to a lua function, such that the C function could fire events in lua, I was planning to use the:
lua_register
function; however I can't seem to find a way to bind my lua function like this, it would seem I'm in need of a lua function that does the same, but from the lua side, I was thinking about making some hack, by binding a C function into lua, that simply calls 'lua_register', but this seems a bit unsafe to me.
So what should I do instead?
I'm not fully sure I understand what you've asked for. So allow me to explain what I think your question is.
You have some Lua code. In that Lua code, you have a system. This system is, at some point, given one or more events. For each event that it is given, it calls some function or functions that were registered to be called when that particular event was given.
So, this system has two basic functions:
EventSystem:RegisterEventHandler(EventName, Func);
EventSystem:FireEvent(EventName, ...);
The RegisterEventHandler
method will associate the given Func
with the given EventName
, such that when FireEvent
is called later, Func
will be called if the EventName
given to FireEvent
is the same one Func
was registered with.
Now you want to have C code be able to register C functions as event handlers. So it's time to talk about registering C functions in Lua.
The C API call lua_register
is actually a macro. It creates a C function on the Lua stack, then puts it in the global table, using the string index given to lua_register
. These are two separate operations; lua_register
is just a convenience function that makes them the same.
What you want is to call RegisterEventHandler
from C code, passing the C function as the third parameter (remember: the first parameter is self
, because I called RegisterEventHandler
with :
instead of .
. If you're using a global event system rather than an object oriented one, you only have two parameters). This requires two things:
- You have to know how to call Lua functions from C code.
- You have to know how to pass a C function to Lua code.
Step 1: It's all done via the Lua stack (I'll assume you know how that works. If not, I have a pretty substantial answer that explains most everything you might want to know about it).
The first thing you need to do is get the function you want to call onto the stack. To do that, you need to get an event system object (again, if your event system is global, just get the global table) and push it onto the stack. How you do that depends on where your event system objects are stored. Presumably you can get them through the global table.
Once you have the event system on the stack, you just index it with the "RegisterEventHandler"
string, which will return to you the Lua function we need.
Next, we push our parameters onto the stack, from first to last. The first parameter is the event system object; it's probably still on the stack, so we can copy it. The second is the event name, and that's easy to push. The third is the C function. Which leads us to:
Step 2: lua_register
is not going to get the job done. It's too heavy handed; it puts the C function in the global table. We need it on the stack. So we must use a lower level function: lua_pushcclosure
. Or lua_pushcfunction
, if you don't need upvalues.
These functions take a C function, wrap it up in Lua, and push it onto the Lua stack.
Now that the 3 parameters are on the stack, we can call the event registration function with a call to lua_pcall
. Or your favorite Lua function calling function; however you wish to do it. Lua will consume the 3 parameters and the function itself, so that they are no longer on the stack.
And since the event registration function probably doesn't return values, the stack will be where it was right before we got the function onto the stack (but not before we started, depending on how much cleanup was done while getting the function).
After this, your C function will be registered with the event handler for that event name.
精彩评论