调用举例
public Text[] grayTextArray; public static void __Register(RealStatePtr L) { Utils.RegisterFunc(L, Utils.GETTER_IDX, "grayTextArray", _g_get_grayTextArray); } static int _g_get_grayTextArray(RealStatePtr L) { ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L); FpUI.FpButton gen_to_be_invoked = (FpUI.FpButton)translator.FastGetCSObj(L, 1); translator.Push(L, gen_to_be_invoked.grayTextArray); return 1; } --lua local image_array = button.grayTextArray if image_array and image_array.Length > 0 then for i = 0, image_array.Length - 1 do local image = image_array[i] end end
欸,好奇怪,传过去的明明是udata为什么能直接调用?多亏了如下代码:
//LuaEnv.cs public LuaEnv() { rawL = LuaAPI.luaL_newstate(); translator = new ObjectTranslator(this, rawL); translator.createFunctionMetatable(rawL); translator.OpenLib(rawL); translator.CreateArrayMetatable(rawL); } //ObjectTranslator.cs public void OpenLib(RealStatePtr L){ LuaAPI.lua_createtable(L, 1, 4); // 4 for __gc, __tostring, __index, __newindex common_array_meta = LuaAPI.luaL_ref(L, LuaIndexes.LUA_REGISTRYINDEX); //只留位,没有具体设置 } //ObjectTranslator.cs public void CreateArrayMetatable(RealStatePtr L) { Utils.BeginObjectRegister(null, L, this, 0, 0, 1, 0, common_array_meta); Utils.RegisterFunc(L, Utils.GETTER_IDX, "Length", StaticLuaCallbacks.ArrayLength); Utils.EndObjectRegister(null, L, this, null, null, typeof(System.Array), StaticLuaCallbacks.ArrayIndexer, StaticLuaCallbacks.ArrayNewIndexer); }
在LuaEnv初始化的时候,就为Array设置了元表。这三个方法已经在前面wrap的注册里面提过了,值得注意的是这里都是objectRegister,并没有注册类。但是从lua层的CS表中,却可以发现CS.System.Array,应该是lua层调用的CS.System.Array访问到的吧。可是很奇怪,我在init_xlua里面加上了local a = CS.System.Array之后,去掉LuaEnv里面的translator.CreateArrayMetatable(rawL);却报错了,待我再研究研究。
看了下,是SetCSTable出问题了。调用链如下:

原因也很简单,因为C#层的CS还没存在注册表中呢,也就是LuaAPI.xlua_pushasciistring(L, LuaEnv.CSHARP_NAMESPACE); LuaAPI.lua_rawget(L, LuaIndexes.LUA_REGISTRYINDEX);这两行代码取不到东西。
将lua代码放到下面,初始化的时候不报错了(Array Class可以正常访问)。但是访问array对象的时候出问题了,具体我觉得应该看看Utils.ReflectionWrap这个方法,后面再说吧
LuaAPI.xlua_pushasciistring(rawL, CSHARP_NAMESPACE); if (0 != LuaAPI.xlua_getglobal(rawL, "CS")) { throw new Exception("get CS fail!"); } LuaAPI.lua_rawset(rawL, LuaIndexes.LUA_REGISTRYINDEX); DoString(set_array, "set_array"); private string set_array = @" local a = CS.System.Array ";