我不完全確定我明白你的要求。所以讓我解釋一下我認爲你的問題是什麼。
你有一些Lua代碼。在那個Lua代碼中,你有一個系統。這個系統在某個時候給了一個或多個事件。對於每個給定的事件,它會調用一些函數或函數,這些函數在給定特定事件時被註冊爲被調用。
因此,該系統具有兩個基本功能:
EventSystem:RegisterEventHandler(EventName, Func);
EventSystem:FireEvent(EventName, ...);
的RegisterEventHandler
方法給出Func
與給定EventName
聯繫起來,這樣當FireEvent
稍後被調用,Func
將被告知是否給予EventName
叫FireEvent
與Func
是一樣的。
現在,您希望讓C代碼能夠將C函數註冊爲事件處理函數。所以現在是時候談論在Lua中註冊C函數了。
C API調用lua_register
實際上是一個宏。它在Lua堆棧上創建一個C函數,然後使用給定的字符串索引將其放入全局表中。lua_register
。這兩個是分開的操作; lua_register
只是一個使它們相同的便利功能。
你想要的是調用RegisterEventHandler
從C代碼,通過C函數作爲第三個參數(記住:第一個參數是self
,因爲我叫RegisterEventHandler
與:
而不是.
如果您使用的是全球性的活動系統而不是一個面向對象的系統,你只有兩個參數)。這需要兩件事:
- 你必須知道如何從C代碼中調用Lua函數。
- 你必須知道如何將C函數傳遞給Lua代碼。
第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
,如果你不需要upvalues。
這些函數採用C函數,將其包裝在Lua中,並將其推入Lua堆棧。
現在3個參數在堆棧上,我們可以調用事件註冊函數lua_pcall
。或者你最喜歡的Lua函數調用函數;但是你希望這樣做。 Lua將使用3個參數和函數本身,以便它們不再處於堆棧中。
而且由於事件註冊函數可能不會返回值,所以在我們將函數放入堆棧之前(但不是在開始之前),堆棧將處於正確的位置,具體取決於獲取功能)。
之後,你的C函數將被註冊到該事件名稱的事件處理程序中。
我很抱歉讓你失望,但我實際上正在尋找的是從C調用'FireEvent'的方法,因爲我希望我的lua系統知道遊戲引擎狀態。 – Skeen
@Skeen:那就叫它。按照我的建議,只使用不同的名稱和參數。當然,不要在Lua中創建C函數。只需在Lua堆棧中調用你想調用的函數,然後將你想要使用的參數放在堆棧上,然後調用該函數即可。 –
很明顯啊! - 謝謝! – Skeen