【Lua与C#交互⑤】Lua中的注册表和引用系统

在导入了xlua或者tolua后,我们能在lua代码里写CS.UnityEngine.xxx来调用unity的API。那么这个功能是如何实现的呢?为了解开这个疑惑,我们需要了解lua里面的注册表和引用系统。

注册表(Registry)是一个全局的table,它只能被C代码访问。通常,可以用它来保存那种需要在几个模块中共享的数据。注册表由一个叫LUA_REGISTRYINDEX的索引可以找到。
它在lua的c源码里被定义如下。
《【Lua与C#交互⑤】Lua中的注册表和引用系统》
它是一个伪索引(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

最终打印的结果如下:
《【Lua与C#交互⑤】Lua中的注册表和引用系统》

这就是本节全部内容。
github工程
对应的是Examples/05_Registry

关于作者:

  • 水曜日鸡,简称水鸡,ACG宅。曾参与索尼中国之星项目研发,具有2D联网多人动作游戏开发经验。

CSDN博客:https://blog.csdn.net/j756915370
知乎专栏:https://zhuanlan.zhihu.com/c_1241442143220363264
交流学习群:891809847

    原文作者:水曜日鸡
    原文地址: https://blog.csdn.net/j756915370/article/details/106875122
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞