【Lua與C#交互⑤】Lua中的註冊表和引用系統

在導入了xlua或者tolua後,我們能在lua代碼裏寫CS.UnityEngine.xxx來調用unity的API。那麼這個功能是如何實現的呢?爲了解開這個疑惑,我們需要了解lua裏面的註冊表和引用系統。


註冊表(Registry)是一個全局的table,它只能被C代碼訪問。通常,可以用它來保存那種需要在幾個模塊中共享的數據。註冊表由一個叫LUA_REGISTRYINDEX的索引可以找到。
它在lua的c源碼裏被定義如下。
在這裏插入圖片描述
它是一個僞索引(Pseudo-Index)。爲什麼叫僞索引?因爲這個索引對應的值不在棧上。而我們平常看見的-1,-2,1,2這些索引的值都在棧上。爲了不跟這些正常索引衝突,僞索引被設得很小。


除了註冊表之外,lua還提供了一個引用系統,方便我們往註冊表裏註冊值和取值。
先說註冊:

int luaL_ref (lua_State *L, int t)

L傳入luaState的指針,t傳入LUA_REGISTRYINDEX。這個函數的作用是彈出棧頂的值,並且用一個新分配的整數key把這個值註冊到註冊表裏,然後返回這個整數key。這個key被稱爲"引用"。

再來看怎麼取值:

int lua_rawgeti (lua_State *L, int index, lua_Integer n)

L傳入luaState的指針,index傳入LUA_REGISTRYINDEX,n傳入上一個函數返回的整數key。作用是把註冊表裏的key對應的值壓棧

最後是釋放該值:

void luaL_unref (lua_State *L, int t, int ref)

L傳入luaState的指針,t傳入LUA_REGISTRYINDEX,ref傳入luaL_ref返回的整數key。


需要注意的是LUA_REGISTRYINDEX在c端和c#端使用的需要是同一個值 。要麼像tolua在c端把lua源碼的LUA_REGISTRYINDEX改了,要麼像xlua,在c端提供一個api把值傳給c#端。這裏我參照(照抄)xlua的做法。

LUA_API int jlua_get_registry_index() {
	return LUA_REGISTRYINDEX;
}

接下來我們在c#端寫一個測試案例:

LuaState lua = new LuaState();
LuaIndexes.LUA_REGISTRYINDEX = LuaDLL.jlua_get_registry_index();

lua.DoFile( "05" );
//把'foo'這個函數壓棧
LuaDLL.lua_getglobal( lua.L, "foo" );
Debug.LogFormat( "StackSize:{0},top type is {1}", LuaDLL.lua_gettop( lua.L ), LuaDLL.lua_type( lua.L, -1 ) );
//存放函數到註冊表
int key =  LuaDLL.luaL_ref( lua.L, LuaIndexes.LUA_REGISTRYINDEX );
Debug.LogFormat( "StackSize:{0}", LuaDLL.lua_gettop( lua.L ) );

LuaDLL.lua_rawgeti( lua.L, LuaIndexes.LUA_REGISTRYINDEX, key );
Debug.LogFormat( "StackSize:{0},top type is {1}", LuaDLL.lua_gettop( lua.L ), LuaDLL.lua_type( lua.L, -1 ) );
LuaDLL.lua_pcall( lua.L, 0, 0, 0 );
Debug.LogFormat( "StackSize:{0}", LuaDLL.lua_gettop( lua.L ) );

LuaDLL.luaL_unref( lua.L, LuaIndexes.LUA_REGISTRYINDEX, key );
lua.Dispose();
lua = null;

其中的05.lua裏的代碼如下:

function foo()
    print("helloworld")
end

最終打印的結果如下:
在這裏插入圖片描述


這就是本節全部內容。
github工程
對應的是Examples/05_Registry


關於作者:

  • 水曜日雞,簡稱水雞,ACG宅。曾參與索尼中國之星項目研發,具有2D聯網多人動作遊戲開發經驗。

CSDN博客:https://blog.csdn.net/j756915370
知乎專欄:https://zhuanlan.zhihu.com/c_1241442143220363264
交流學習羣:891809847

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章