定义System.Array的行为

调用举例

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
";

发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

大纲

Share the Post:
滚动至顶部