####0 ulua, slua 實現分紅兩個部分:c層和c#層c#
c層主要是lua或者luajit,加一個c層的接口,以及一些能夠添加的第三方庫閉包
c#層:主要解決:函數
如何調用lua代碼lua
lua如何調用c#代碼對象
c#對象如何傳遞給lua索引
lua對象如何傳遞給c#接口
這些問題。生命週期
####1調用lua代碼資源
LuaDll 導入了lua相關的c接口,用於c#調用字符串
#####2lua調用c#方法
經過lua_pushcfunction 將c#函數轉化爲c函數,傳遞給lua代碼,接着能夠設置lua中table的某個成員對應於這個c函數, 這種方式,c#中的函數若是被gc了,會有問題。
lua_pushcfunction
lua_setglobal
上面能夠簡單的設定全局函數
#####3 c#對象傳遞給給lua代碼
跨語言傳遞對象,最簡單的方式,將對象序列化爲字符串傳遞過去;
對於簡單值對象,能夠序列化方式傳遞;
複雜類對象,能夠建立一個LuaTable,用於對應於c#中的類對象,將c#類的函數註冊到table中,將對屬性的訪問和設置,註冊get set 函數便可。
在c#層能夠保存一個id到object的映射表,當須要從Lua調用c#對象的方法,只須要告知對象的id,接着在C#層根據id得到到對象便可
####4 Lua對象傳遞給c#
Lua對象包括簡單的值對象,複雜的table對象。
值對象直接從堆棧上返回
table對象在c# LuaTable來表示,在lua中能夠將lua的table存儲起來,經過id進行索引,而將id傳給 c#層,當c#層須要訪問table數據,只須要根據id調用對應接口便可。
####5 靜態綁定代碼生成
當lua中須要調用c#中某個類的接口的時候,首先lua須要得到這個c#對象,接着調用c#對象函數接口;
Lua中得到某個c#對象,能夠是經過c#的靜態方法,或者成員方法。
簡單的從靜態方法開始考慮:
首先Lua中須要有該類的一個Table,這個table中的有靜態方法的c函數能夠供lua調用。
Lua的全局global table能夠註冊名字,這樣在lua全局代碼中就能夠調用這個名字;
當調用某個方法返回c#對象,將c#對象放置到c#的列表中,而將對應的id返回給lua。
####6 對象生命週期管理
當Lua中引用c#對象,如何當lua引用結束的時候,通知c#中的管理代碼,來去除對象?
當c#引用lua對象,如何管理Lua對象的生命週期呢?
Lua table能夠添加一個metatable用於重載lua系統默認的一些接口的操做,重載__gc 接口,能夠再lua 回收資源時候,調用c#代碼進行清理工做,這樣當lua不須要c#對象的時候,能夠將對象回收。
c#引用luatable對象,如何釋放掉?c#對象能夠實現 IDisposable 接口,當C#對象被GC的時候,釋放對lua對象的引用。
經過 luaL_ref luaL_unref, 即將 table中對應id的項狀況。
####7 異常處理
當lua調用c#代碼發生異常,在c#代碼中添加了異常捕獲,當出現異常將向堆棧壓入false以及異常信息,而若是沒有異常,將壓入true,以及正常的返回值;
而在壓入c#函數到lua中時候,壓入一個閉包,而在lua的這個閉包調用正常的csharp函數,檢查返回是否有異常,存在異常,則拋出一個lua_error,或者用lua的 assert拋出一個異常
當c#調用lua代碼發生異常,c#能夠使用lua_pcall 來執行lua代碼,能夠傳入相應的異常處理函數,來打印出lua的異常以及堆棧信息。
####6 一種基於Component 提供接口的Lua代碼寫法