当前位置: 首页 > news >正文

Xlua原理 二

一已经介绍了初步的lua与C#通信的原理,和xlua的LuaEnv的初始化内容。

这边介绍下Wrap文件。

一.Wrap介绍

导入xlua后可以看到会多出上图菜单。

点击后生成一堆wrap文件,这些文件是lua调用C#时进行映射查找用的中间代码。这样就不需要去反射调用节约性能。

这里以Vector3Wrap文件为例:

先看一眼Wrap文件结构

   public class UnityEngineVector3Wrap {public static void __Register(RealStatePtr L){ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);System.Type type = typeof(UnityEngine.Vector3);Utils.BeginObjectRegister(type, L, translator, 6, 6, 6, 3);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__add", __AddMeta);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__sub", __SubMeta);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__unm", __UnmMeta);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__mul", __MulMeta);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__div", __DivMeta);Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "__eq", __EqMeta);Utils.RegisterFunc(L, Utils.METHOD_IDX, "Set", _m_Set);Utils.RegisterFunc(L, Utils.METHOD_IDX, "Scale", _m_Scale);Utils.RegisterFunc(L, Utils.METHOD_IDX, "GetHashCode", _m_GetHashCode);Utils.RegisterFunc(L, Utils.METHOD_IDX, "Equals", _m_Equals);Utils.RegisterFunc(L, Utils.METHOD_IDX, "Normalize", _m_Normalize);Utils.RegisterFunc(L, Utils.METHOD_IDX, "ToString", _m_ToString);...}...}    
 private void Demo4(){LuaEnv luaenv = new LuaEnv();luaenv.DoString(@"local v1 = CS.UnityEngine.Vector3(10,10,10)local v2 = v1.normalizedCS.UnityEngine.Debug.Log(v2.x)local v3 = v1 + v2local v4 = CS.UnityEngine.Vector3.Distance(v1,v2)v1:Set(5,6,7)CS.UnityEngine.Debug.Log(v1.x)");luaenv.Dispose();}

以调用到normalized为例

Utils.RegisterFunc(L, Utils.GETTER_IDX, "normalized", _g_get_normalized);....[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _g_get_normalized(RealStatePtr L){try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);UnityEngine.Vector3 gen_to_be_invoked;translator.Get(L, 1, out gen_to_be_invoked);translator.PushUnityEngineVector3(L, gen_to_be_invoked.normalized);} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return 1;}

上面那步在lua虚拟机注册normalized,对应是C#里的函数。

函数中先获得Vector3变量然后调用C#中的normalized,最后再进行压栈操作供lua使用。

这块看出来,实际上lua还是去调用C#的代码,并且伴随压栈出栈操作。这就是为什么我们的lua的代码减少 . 这样的调用能节约一些性能的原因。

再换个函数Set

       [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _m_Set(RealStatePtr L){try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);UnityEngine.Vector3 gen_to_be_invoked;translator.Get(L, 1, out gen_to_be_invoked);{float _newX = (float)LuaAPI.lua_tonumber(L, 2);float _newY = (float)LuaAPI.lua_tonumber(L, 3);float _newZ = (float)LuaAPI.lua_tonumber(L, 4);gen_to_be_invoked.Set( _newX, _newY, _newZ );translator.UpdateUnityEngineVector3(L, 1, gen_to_be_invoked);return 0;}} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}}

前面的部分跟normalized差不多看下UpdateUnityEngineVector3部分

public void UpdateUnityEngineVector3(RealStatePtr L, int index, UnityEngine.Vector3 val){if (LuaAPI.lua_type(L, index) == LuaTypes.LUA_TUSERDATA){if (LuaAPI.xlua_gettypeid(L, index) != UnityEngineVector3_TypeID){throw new Exception("invalid userdata for UnityEngine.Vector3");}IntPtr buff = LuaAPI.lua_touserdata(L, index);if (!CopyByValue.Pack(buff, 0,  val)){throw new Exception("pack fail for UnityEngine.Vector3 ,value="+val);}}else{throw new Exception("try to update a data with lua type:" + LuaAPI.lua_type(L, index));}}

这里看到对应lua来说C#的结构体、类都是UserData。C#想要去改变lua内的内存使用

CopyByValue.Pack函数进行拷贝

再拿个GameObject的Component举例,加深下印象:

luaenv.DoString(@"local v1 = CS.UnityEngine.GameObject()local v2 = v1:AddComponent(typeof(CS.UnityEngine.Camera))");[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _m_AddComponent(RealStatePtr L){try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);UnityEngine.GameObject gen_to_be_invoked = (UnityEngine.GameObject)translator.FastGetCSObj(L, 1);{System.Type _componentType = (System.Type)translator.GetObject(L, 2, typeof(System.Type));var gen_ret = gen_to_be_invoked.AddComponent( _componentType );translator.Push(L, gen_ret);return 1;}} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}}

这里有个函数getCsObj用于取游戏对象

private object getCsObj(RealStatePtr L, int index, int udata){object obj;if (udata == -1){if (LuaAPI.lua_type(L, index) != LuaTypes.LUA_TUSERDATA) return null;Type type = GetTypeOf(L, index);if (type == typeof(decimal)){decimal v;Get(L, index, out v);return v;}GetCSObject get;if (type != null && custom_get_funcs.TryGetValue(type, out get)){return get(L, index);}else{return null;}}else if (objects.TryGetValue(udata, out obj)){
#if !UNITY_5 && !XLUA_GENERAL && !UNITY_2017 && !UNITY_2017_1_OR_NEWER && !UNITY_2018if (obj != null && obj is UnityEngine.Object && ((obj as UnityEngine.Object) == null)){//throw new UnityEngine.MissingReferenceException("The object of type '"+ obj.GetType().Name +"' has been destroyed but you are still trying to access it.");return null;}
#endifreturn obj;}return null;}

这里从一个objects字典去查找游戏的对象。跟Vector3有区别。lua创建GameObject的过程会走CS的元表方法(在上篇有介绍),调用c#的Import方法,会把这个GameObject进行注册方法,加入到objects进行维护。

额外测试了删除,发现如果不触发gc,object池不会删除对象,哪怕C#实际上已经删除了

总结:Wrap文件是lua与C#通信中间代码文件,主要实现方式就是从lua堆栈取出lua数据对象,调用C#代码然后把结果再压栈到堆栈中。

像代码 

local v1 = CS.UnityEngine.Vector3(1,2,3)

v1:Set(4,5,6)

性能明显要优于

v1.x = 4

v2.y = 5

v3.z = 6

压栈少了4次,拷贝次数少了2次

二.Wrap文件生成

流程:

1.Generator收集这种类型需要导出的对象

2.通过LuaTemplate把对应的.tpl.txt文件转成可执行的lua代码

3.在GenOne方法里给上一步生成的lua代码赋值全局变量

4.执行lua代码生成wrap文件

映射模板目录:

生成中间代码文件部分

XLua.Utils.GetAllTypes:收集工程所有元数据

ps:这步可以直接进行改造,让其直接对有效元数据进行筛选,稍微节约一点编译时间

GetGenConfig:对元数据进行过滤筛选出需要lua与C#通信的元数据

以Lua通信C#代码为例:

先生成一个List,然后去获取所有打上LuaCallCSharp标签的元数据,进行添加,最后在用Linq表达式进行一遍筛选。

执行脚本TemplateCommon,在lua里填充table数据,组织好后去生成Wrap文件

对于每个类都会走到GenOne来生成Wrap文件

以GameObjectWrap文件生成为例:

模板对应文件:

#if USE_UNI_LUA
using LuaAPI = UniLua.Lua;
using RealStatePtr = UniLua.ILuaState;
using LuaCSFunction = UniLua.CSharpFunctionDelegate;
#else
using LuaAPI = XLua.LuaDLL.Lua;
using RealStatePtr = System.IntPtr;
using LuaCSFunction = XLua.LuaDLL.lua_CSFunction;
#endifusing XLua;
using System.Collections.Generic;
<%ForEachCsList(namespaces, function(namespace)%>using <%=namespace%>;<%end)%>
<%
require "TemplateCommon"local OpNameMap = {op_Addition = "__AddMeta",op_Subtraction = "__SubMeta",op_Multiply = "__MulMeta",op_Division = "__DivMeta",op_Equality = "__EqMeta",op_UnaryNegation = "__UnmMeta",op_LessThan = "__LTMeta",op_LessThanOrEqual = "__LEMeta",op_Modulus = "__ModMeta",op_BitwiseAnd = "__BandMeta",op_BitwiseOr = "__BorMeta",op_ExclusiveOr = "__BxorMeta",op_OnesComplement = "__BnotMeta",op_LeftShift = "__ShlMeta",op_RightShift = "__ShrMeta",
}local OpCallNameMap = {op_Addition = "+",op_Subtraction = "-",op_Multiply = "*",op_Division = "/",op_Equality = "==",op_UnaryNegation = "-",op_LessThan = "<",op_LessThanOrEqual = "<=",op_Modulus = "%",op_BitwiseAnd = "&",op_BitwiseOr = "|",op_ExclusiveOr = "^",op_OnesComplement = "~",op_LeftShift = "<<",op_RightShift = ">>",
}local obj_method_count = 0
local obj_getter_count = 0
local obj_setter_count = 0
local meta_func_count = operators.Count
local cls_field_count = 1
local cls_getter_count = 0
local cls_setter_count = 0ForEachCsList(methods, function(method)if method.IsStatic thencls_field_count = cls_field_count + 1elseobj_method_count = obj_method_count + 1end 
end)ForEachCsList(events, function(event)if event.IsStatic thencls_field_count = cls_field_count + 1elseobj_method_count = obj_method_count + 1end 
end)ForEachCsList(getters, function(getter)if getter.IsStatic thenif getter.ReadOnly thencls_field_count = cls_field_count + 1elsecls_getter_count = cls_getter_count + 1endelseobj_getter_count = obj_getter_count + 1end 
end)ForEachCsList(setters, function(setter)if setter.IsStatic thencls_setter_count = cls_setter_count + 1elseobj_setter_count = obj_setter_count + 1end 
end)ForEachCsList(lazymembers, function(lazymember)if lazymember.IsStatic == 'true' thenif 'CLS_IDX' == lazymember.Index thencls_field_count = cls_field_count + 1elseif 'CLS_GETTER_IDX' == lazymember.Index thencls_getter_count = cls_getter_count + 1elseif 'CLS_SETTER_IDX' == lazymember.Index thencls_setter_count = cls_setter_count + 1endelseif 'METHOD_IDX' == lazymember.Index thenobj_method_count = obj_method_count + 1elseif 'GETTER_IDX' == lazymember.Index thenobj_getter_count = obj_getter_count + 1elseif 'SETTER_IDX' == lazymember.Index thenobj_setter_count = obj_setter_count + 1endend
end)local generic_arg_list, type_constraints = GenericArgumentList(type)%>
namespace XLua.CSObjectWrap
{using Utils = XLua.Utils;public class <%=CSVariableName(type)%>Wrap<%=generic_arg_list%> <%=type_constraints%>{public static void __Register(RealStatePtr L){ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);System.Type type = typeof(<%=CsFullTypeName(type)%>);Utils.BeginObjectRegister(type, L, translator, <%=meta_func_count%>, <%=obj_method_count%>, <%=obj_getter_count%>, <%=obj_setter_count%>);<%ForEachCsList(operators, function(operator)%>Utils.RegisterFunc(L, Utils.OBJ_META_IDX, "<%=(OpNameMap[operator.Name]):gsub('Meta', ''):lower()%>", <%=OpNameMap[operator.Name]%>);<%end)%><%ForEachCsList(methods, function(method) if not method.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=method.Name%>", _m_<%=method.Name%>);<% end end)%><%ForEachCsList(events, function(event) if not event.IsStatic then %>Utils.RegisterFunc(L, Utils.METHOD_IDX, "<%=event.Name%>", _e_<%=event.Name%>);<% end end)%><%ForEachCsList(getters, function(getter) if not getter.IsStatic then %>Utils.RegisterFunc(L, Utils.GETTER_IDX, "<%=getter.Name%>", _g_get_<%=getter.Name%>);<%end end)%><%ForEachCsList(setters, function(setter) if not setter.IsStatic then %>Utils.RegisterFunc(L, Utils.SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);<%end end)%><%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);<%end end)%>Utils.EndObjectRegister(type, L, translator, <% if type.IsArray or ((indexers.Count or 0) > 0) then %>__CSIndexer<%else%>null<%end%>, <%if type.IsArray or ((newindexers.Count or 0) > 0) then%>__NewIndexer<%else%>null<%end%>,null, null, null);Utils.BeginClassRegister(type, L, __CreateInstance, <%=cls_field_count%>, <%=cls_getter_count%>, <%=cls_setter_count%>);<%ForEachCsList(methods, function(method) if method.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=method.Overloads[0].Name%>", _m_<%=method.Name%>);<% end end)%><%ForEachCsList(events, function(event) if event.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_IDX, "<%=event.Name%>", _e_<%=event.Name%>);<% end end)%><%ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then %>Utils.RegisterObject(L, translator, Utils.CLS_IDX, "<%=getter.Name%>", <%=CsFullTypeName(type).."."..getter.Name%>);<%end end)%><%ForEachCsList(getters, function(getter) if getter.IsStatic and (not getter.ReadOnly) then %>Utils.RegisterFunc(L, Utils.CLS_GETTER_IDX, "<%=getter.Name%>", _g_get_<%=getter.Name%>);<%end end)%><%ForEachCsList(setters, function(setter) if setter.IsStatic then %>Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, "<%=setter.Name%>", _s_set_<%=setter.Name%>);<%end end)%><%ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then %>Utils.RegisterLazyFunc(L, Utils.<%=lazymember.Index%>, "<%=lazymember.Name%>", type, <%=lazymember.MemberType%>, <%=lazymember.IsStatic%>);<%end end)%>Utils.EndClassRegister(type, L, translator);}[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int __CreateInstance(RealStatePtr L){<% if constructors.Count == 0 and (not type.IsValueType)  then %>return LuaAPI.luaL_error(L, "<%=CsFullTypeName(type)%> does not have a constructor!");<% else %>try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<% local hasZeroParamsCtor = falseForEachCsList(constructors, function(constructor, ci)local parameters = constructor:GetParameters()if parameters.Length == 0 thenhasZeroParamsCtor = trueendlocal def_count = constructor_def_vals[ci]local param_count = parameters.Lengthlocal in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)local real_param_count = param_count - def_countlocal has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])local in_pos = 0%>if(LuaAPI.lua_gettop(L) <%=has_v_params and ">=" or "=="%> <%=in_num + 1 - def_count - (has_v_params and 1 or 0)%><%ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end local parameterType = parameter.ParameterTypeif has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1%> && <%=GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)%><% endend)%>){<%ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end %><%=GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%>;<%end)%>var gen_ret = new <%=CsFullTypeName(type)%>(<%ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end; if pi ~=0 then %><%=', '%><% end ;if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef and not parameter.IsIn then %>ref <% end %><%=LocalName(parameter.Name)%><% end)%>);<%=GetPushStatement(type, "gen_ret")%>;<%local in_pos = 0ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1endif parameter.ParameterType.IsByRef then%><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;<%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))%>;<%end%><%endend)%>return <%=out_num + 1%>;}<%end)if (not hasZeroParamsCtor) and type.IsValueType then%>if (LuaAPI.lua_gettop(L) == 1){<%=GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")%>;return 1;}<%end%>}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%> constructor!");<% end %>}<% if type.IsArray or ((indexers.Count or 0) > 0) then %>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]public static int __CSIndexer(RealStatePtr L){<%if type.IsArray then %>try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2)){int index = (int)LuaAPI.lua_tonumber(L, 2);<%=GetSelfStatement(type)%>;LuaAPI.lua_pushboolean(L, true);<%=GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")%>;return 2;}}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}<%elseif indexers.Count > 0 then%>try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%ForEachCsList(indexers, function(indexer)local paramter = indexer:GetParameters()[0]%>if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(paramter.ParameterType, 2)%>){<%=GetSelfStatement(type)%>;<%=GetCasterStatement(paramter.ParameterType, 2, "index", true)%>;LuaAPI.lua_pushboolean(L, true);<%=GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")%>;return 2;}<%end)%>}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}<%end%>LuaAPI.lua_pushboolean(L, false);return 1;}<% end %><%if type.IsArray or ((newindexers.Count or 0) > 0) then%>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]public static int __NewIndexer(RealStatePtr L){<%if type.IsArray or newindexers.Count > 0 then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%><%if type.IsArray then local elementType = type:GetElementType()%>try {if (<%=GetCheckStatement(type, 1)%> && LuaAPI.lua_isnumber(L, 2) && <%=GetCheckStatement(elementType, 3)%>){int index = (int)LuaAPI.lua_tonumber(L, 2);<%=GetSelfStatement(type)%>;<%=GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")%>;LuaAPI.lua_pushboolean(L, true);return 1;}}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}<%elseif newindexers.Count > 0 then%>try {<%ForEachCsList(newindexers, function(newindexer)local keyType = newindexer:GetParameters()[0].ParameterTypelocal valueType = newindexer:GetParameters()[1].ParameterType%>if (<%=GetCheckStatement(type, 1)%> && <%=GetCheckStatement(keyType, 2)%> && <%=GetCheckStatement(valueType, 3)%>){<%=GetSelfStatement(type)%>;<%=GetCasterStatement(keyType, 2, "key", true)%>;<%if IsStruct(valueType) then%><%=GetCasterStatement(valueType, 3, "gen_value", true)%>;gen_to_be_invoked[key] = gen_value;<%else%><%=GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")%>;<%end%>LuaAPI.lua_pushboolean(L, true);return 1;}<%end)%>}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}<%end%>LuaAPI.lua_pushboolean(L, false);return 1;}<% end %><%ForEachCsList(operators, function(operator) %>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int <%=OpNameMap[operator.Name]%>(RealStatePtr L){<% if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then %>try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%ForEachCsList(operator.Overloads, function(overload)local left_param = overload:GetParameters()[0]local right_param = overload:GetParameters()[1]%>if (<%=GetCheckStatement(left_param.ParameterType, 1)%> && <%=GetCheckStatement(right_param.ParameterType, 2)%>){<%=GetCasterStatement(left_param.ParameterType, 1, "leftside", true)%>;<%=GetCasterStatement(right_param.ParameterType, 2, "rightside", true)%>;<%=GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")%>;return 1;}<%end)%>}catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return LuaAPI.luaL_error(L, "invalid arguments to right hand of <%=OpCallNameMap[operator.Name]%> operator, need <%=CsFullTypeName(type)%>!");<%else%>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);try {<%=GetCasterStatement(type, 1, "rightside", true)%>;<%=GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")%>;} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return 1;<%end%>}<%end)%><%ForEachCsList(methods, function(method)%>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _m_<%=method.Name%>(RealStatePtr L){try {<%local need_obj = not method.IsStaticif MethodCallNeedTranslator(method) then%>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%><%if need_obj then%><%=GetSelfStatement(type)%>;<%end%><%if method.Overloads.Count > 1 then%>int gen_param_count = LuaAPI.lua_gettop(L);<%end%><%ForEachCsList(method.Overloads, function(overload, oi)local parameters = MethodParameters(overload)local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)local param_offset = method.IsStatic and 0 or 1local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)local in_pos = 0local has_return = (overload.ReturnType.FullName ~= "System.Void")local def_count = method.DefaultValues[oi]local param_count = parameters.Lengthlocal real_param_count = param_count - def_countlocal has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])if method.Overloads.Count > 1 then%>if(gen_param_count <%=has_v_params and ">=" or "=="%> <%=in_num+param_offset-def_count - (has_v_params and 1 or 0)%><%ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endlocal parameterType = parameter.ParameterTypeif has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1; %>&& <%=GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)%><% end end)%>) <%end%>{<%if overload.Name == "get_Item" and overload.IsSpecialName thenlocal keyType = overload:GetParameters()[0].ParameterType%><%=GetCasterStatement(keyType, 2, "key", true)%>;<%=GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")%>;<%elseif overload.Name == "set_Item" and overload.IsSpecialName thenlocal keyType = overload:GetParameters()[0].ParameterTypelocal valueType = overload:GetParameters()[1].ParameterType%><%=GetCasterStatement(keyType, 2, "key", true)%>;<%=GetCasterStatement(valueType, 3, "gen_value", true)%>;gen_to_be_invoked[key] = gen_value;<% elsein_pos = 0;ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end%><%if not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1%><%=GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)%><%else%><%=CsFullTypeName(parameter.ParameterType)%> <%=LocalName(parameter.Name)%><%end%>;<%end)%><%if has_return then%>    var gen_ret = <%end%><%if method.IsStatic then%><%=CsFullTypeName(type).."."..UnK(overload.Name)%><%else%>gen_to_be_invoked.<%=UnK(overload.Name)%><%end%>( <%ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return endif pi ~= 0 then %>, <% end; if parameter.IsOut and parameter.ParameterType.IsByRef then %>out <% elseif parameter.ParameterType.IsByRef and not parameter.IsIn then %>ref <% end %><%=LocalName(parameter.Name)%><% end) %> );<%if has_return then%>    <%=GetPushStatement(overload.ReturnType, "gen_ret")%>;<%endlocal in_pos = 0ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1endif parameter.ParameterType.IsByRef then%><%=GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))%>;<%if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then %><%=GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))%>;<%end%><%endend)end%><%if NeedUpdate(type) and not method.IsStatic then%><%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;<%end%>return <%=out_num+(has_return and 1 or 0)%>;}<% end)%>} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}<%if method.Overloads.Count > 1 then%>return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=method.Overloads[0].Name%>!");<%end%>}<% end)%><%ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then return end --readonly static%>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _g_get_<%=getter.Name%>(RealStatePtr L){try {<%if AccessorNeedTranslator(getter) then %>    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%><%if not getter.IsStatic then%><%=GetSelfStatement(type)%>;<%=GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))%>;<% else %>    <%=GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))%>;<% end%>} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return 1;}<%end)%><%ForEachCsList(setters, function(setter)local is_struct = IsStruct(setter.Type)%>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _s_set_<%=setter.Name%>(RealStatePtr L){try {<%if AccessorNeedTranslator(setter) then %>ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);<%end%><%if not setter.IsStatic then %><%=GetSelfStatement(type)%>;<%if is_struct then %><%=GetCasterStatement(setter.Type, 2, "gen_value", true)%>;gen_to_be_invoked.<%=UnK(setter.Name)%> = gen_value;<% else %><%=GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))%>;<%endelse if is_struct then %><%=GetCasterStatement(setter.Type, 1, "gen_value", true)%>;<%=CsFullTypeName(type)%>.<%=UnK(setter.Name)%> = gen_value;<%else%>    <%=GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))%>;<%endend%><%if NeedUpdate(type) and not setter.IsStatic then%><%=GetUpdateStatement(type, 1, "gen_to_be_invoked")%>;<%end%>} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return 0;}<%end)%><%ForEachCsList(events, function(event) if not event.IsStatic then %>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _e_<%=event.Name%>(RealStatePtr L){try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);int gen_param_count = LuaAPI.lua_gettop(L);<%=GetSelfStatement(type)%>;<%=GetCasterStatement(event.Type, 3, "gen_delegate", true)%>;if (gen_delegate == null) {return LuaAPI.luaL_error(L, "#3 need <%=CsFullTypeName(event.Type)%>!");}if (gen_param_count == 3){<%if event.CanAdd then%>if (LuaAPI.xlua_is_eq_str(L, 2, "+")) {gen_to_be_invoked.<%=UnK(event.Name)%> += gen_delegate;return 0;} <%end%><%if event.CanRemove then%>if (LuaAPI.xlua_is_eq_str(L, 2, "-")) {gen_to_be_invoked.<%=UnK(event.Name)%> -= gen_delegate;return 0;} <%end%>}} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");return 0;}<%end end)%><%ForEachCsList(events, function(event) if event.IsStatic then %>[MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]static int _e_<%=event.Name%>(RealStatePtr L){try {ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);int gen_param_count = LuaAPI.lua_gettop(L);<%=GetCasterStatement(event.Type, 2, "gen_delegate", true)%>;if (gen_delegate == null) {return LuaAPI.luaL_error(L, "#2 need <%=CsFullTypeName(event.Type)%>!");}<%if event.CanAdd then%>if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "+")) {<%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> += gen_delegate;return 0;} <%end%><%if event.CanRemove then%>if (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, "-")) {<%=CsFullTypeName(type)%>.<%=UnK(event.Name)%> -= gen_delegate;return 0;} <%end%>} catch(System.Exception gen_e) {return LuaAPI.luaL_error(L, "c# exception:" + gen_e);}return LuaAPI.luaL_error(L, "invalid arguments to <%=CsFullTypeName(type)%>.<%=event.Name%>!");}<%end end)%>}
}

这里好多的 如namespace,ForEachCsList,CSVariableName等运行时会被对应的GameObject替换。

再打一下这个文件被预编译后的文件:

local __text_gen = {}
table.insert(__text_gen, "#if USE_UNI_LUA\r\nusing LuaAPI = UniLua.Lua;\r\nusing RealStatePtr = UniLua.ILuaState;\r\nusing LuaCSFunction = UniLua.CSharpFunctionDelegate;\r\n#else\r\nusing LuaAPI = XLua.LuaDLL.Lua;\r\nusing RealStatePtr = System.IntPtr;\r\nusing LuaCSFunction = XLua.LuaDLL.lua_CSFunction;\r\n#endif\r\n\r\nusing XLua;\r\nusing System.Collections.Generic;\r\n")
ForEachCsList(namespaces, function(namespace)
table.insert(__text_gen, "using ")
table.insert(__text_gen, tostring(namespace))
table.insert(__text_gen, ";")
end)
table.insert(__text_gen, "\r\n")require "TemplateCommon"local OpNameMap = {op_Addition = "__AddMeta",op_Subtraction = "__SubMeta",op_Multiply = "__MulMeta",op_Division = "__DivMeta",op_Equality = "__EqMeta",op_UnaryNegation = "__UnmMeta",op_LessThan = "__LTMeta",op_LessThanOrEqual = "__LEMeta",op_Modulus = "__ModMeta",op_BitwiseAnd = "__BandMeta",op_BitwiseOr = "__BorMeta",op_ExclusiveOr = "__BxorMeta",op_OnesComplement = "__BnotMeta",op_LeftShift = "__ShlMeta",op_RightShift = "__ShrMeta",
}local OpCallNameMap = {op_Addition = "+",op_Subtraction = "-",op_Multiply = "*",op_Division = "/",op_Equality = "==",op_UnaryNegation = "-",op_LessThan = "<",op_LessThanOrEqual = "<=",op_Modulus = "%",op_BitwiseAnd = "&",op_BitwiseOr = "|",op_ExclusiveOr = "^",op_OnesComplement = "~",op_LeftShift = "<<",op_RightShift = ">>",
}local obj_method_count = 0
local obj_getter_count = 0
local obj_setter_count = 0
local meta_func_count = operators.Count
local cls_field_count = 1
local cls_getter_count = 0
local cls_setter_count = 0ForEachCsList(methods, function(method)if method.IsStatic thencls_field_count = cls_field_count + 1elseobj_method_count = obj_method_count + 1end 
end)ForEachCsList(events, function(event)if event.IsStatic thencls_field_count = cls_field_count + 1elseobj_method_count = obj_method_count + 1end 
end)ForEachCsList(getters, function(getter)if getter.IsStatic thenif getter.ReadOnly thencls_field_count = cls_field_count + 1elsecls_getter_count = cls_getter_count + 1endelseobj_getter_count = obj_getter_count + 1end 
end)ForEachCsList(setters, function(setter)if setter.IsStatic thencls_setter_count = cls_setter_count + 1elseobj_setter_count = obj_setter_count + 1end 
end)ForEachCsList(lazymembers, function(lazymember)if lazymember.IsStatic == 'true' thenif 'CLS_IDX' == lazymember.Index thencls_field_count = cls_field_count + 1elseif 'CLS_GETTER_IDX' == lazymember.Index thencls_getter_count = cls_getter_count + 1elseif 'CLS_SETTER_IDX' == lazymember.Index thencls_setter_count = cls_setter_count + 1endelseif 'METHOD_IDX' == lazymember.Index thenobj_method_count = obj_method_count + 1elseif 'GETTER_IDX' == lazymember.Index thenobj_getter_count = obj_getter_count + 1elseif 'SETTER_IDX' == lazymember.Index thenobj_setter_count = obj_setter_count + 1endend
end)local generic_arg_list, type_constraints = GenericArgumentList(type)table.insert(__text_gen, "\r\nnamespace XLua.CSObjectWrap\r\n{\r\n    using Utils = XLua.Utils;\r\n    public class ")
table.insert(__text_gen, tostring(CSVariableName(type)))
table.insert(__text_gen, "Wrap")
table.insert(__text_gen, tostring(generic_arg_list))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(type_constraints))
table.insert(__text_gen, "\r\n    {\r\n        public static void __Register(RealStatePtr L)\r\n        {\r\n\t\t\tObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\tSystem.Type type = typeof(")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ");\r\n\t\t\tUtils.BeginObjectRegister(type, L, translator, ")
table.insert(__text_gen, tostring(meta_func_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_method_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_getter_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(obj_setter_count))
table.insert(__text_gen, ");\r\n\t\t\t")
ForEachCsList(operators, function(operator)
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.OBJ_META_IDX, \"")
table.insert(__text_gen, tostring((OpNameMap[operator.Name]):gsub('Meta', ''):lower()))
table.insert(__text_gen, "\", ")
table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
table.insert(__text_gen, ");\r\n            ")
end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(methods, function(method) if not method.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, \"")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, "\", _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, ");\r\n\t\t\t")end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(events, function(event) if not event.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.METHOD_IDX, \"")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "\", _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, ");\r\n\t\t\t")end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(getters, function(getter) if not getter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.GETTER_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(setters, function(setter) if not setter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.SETTER_IDX, \"")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "\", _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'false' then 
table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
table.insert(__text_gen, tostring(lazymember.Index))
table.insert(__text_gen, ", \"")
table.insert(__text_gen, tostring(lazymember.Name))
table.insert(__text_gen, "\", type, ")
table.insert(__text_gen, tostring(lazymember.MemberType))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(lazymember.IsStatic))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\tUtils.EndObjectRegister(type, L, translator, ")if type.IsArray or ((indexers.Count or 0) > 0) then 
table.insert(__text_gen, "__CSIndexer")
else
table.insert(__text_gen, "null")
end
table.insert(__text_gen, ", ")
if type.IsArray or ((newindexers.Count or 0) > 0) then
table.insert(__text_gen, "__NewIndexer")
else
table.insert(__text_gen, "null")
end
table.insert(__text_gen, ",\r\n\t\t\t    null, null, null);\r\n\r\n\t\t    Utils.BeginClassRegister(type, L, __CreateInstance, ")
table.insert(__text_gen, tostring(cls_field_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(cls_getter_count))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(cls_setter_count))
table.insert(__text_gen, ");\r\n\t\t\t")
ForEachCsList(methods, function(method) if method.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(method.Overloads[0].Name))
table.insert(__text_gen, "\", _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, ");\r\n            ")end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(events, function(event) if event.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "\", _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, ");\r\n\t\t\t")end end)
table.insert(__text_gen, "\r\n            ")
ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then 
table.insert(__text_gen, "Utils.RegisterObject(L, translator, Utils.CLS_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", ")
table.insert(__text_gen, tostring(CsFullTypeName(type).."."..getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(getters, function(getter) if getter.IsStatic and (not getter.ReadOnly) then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_GETTER_IDX, \"")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "\", _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(setters, function(setter) if setter.IsStatic then 
table.insert(__text_gen, "Utils.RegisterFunc(L, Utils.CLS_SETTER_IDX, \"")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "\", _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\t")
ForEachCsList(lazymembers, function(lazymember) if lazymember.IsStatic == 'true' then 
table.insert(__text_gen, "Utils.RegisterLazyFunc(L, Utils.")
table.insert(__text_gen, tostring(lazymember.Index))
table.insert(__text_gen, ", \"")
table.insert(__text_gen, tostring(lazymember.Name))
table.insert(__text_gen, "\", type, ")
table.insert(__text_gen, tostring(lazymember.MemberType))
table.insert(__text_gen, ", ")
table.insert(__text_gen, tostring(lazymember.IsStatic))
table.insert(__text_gen, ");\r\n            ")
end end)
table.insert(__text_gen, "\r\n\t\t\tUtils.EndClassRegister(type, L, translator);\r\n        }\r\n        \r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int __CreateInstance(RealStatePtr L)\r\n        {\r\n            ")if constructors.Count == 0 and (not type.IsValueType)  then table.insert(__text_gen, "return LuaAPI.luaL_error(L, \"")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, " does not have a constructor!\");")else 
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")local hasZeroParamsCtor = falseForEachCsList(constructors, function(constructor, ci)local parameters = constructor:GetParameters()if parameters.Length == 0 thenhasZeroParamsCtor = trueendlocal def_count = constructor_def_vals[ci]local param_count = parameters.Lengthlocal in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)local real_param_count = param_count - def_countlocal has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])local in_pos = 0table.insert(__text_gen, "if(LuaAPI.lua_gettop(L) ")
table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(in_num + 1 - def_count - (has_v_params and 1 or 0)))
ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end local parameterType = parameter.ParameterTypeif has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(parameterType, in_pos+1, has_v_params and pi == param_count - 1)))endend)
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, pi+2, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
end)
table.insert(__text_gen, "\r\n\t\t\t\t\tvar gen_ret = new ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, "(")
ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return end; if pi ~=0 then 
table.insert(__text_gen, tostring(', '))end ;if parameter.IsOut and parameter.ParameterType.IsByRef then 
table.insert(__text_gen, "out ")elseif parameter.ParameterType.IsByRef and not parameter.IsIn then 
table.insert(__text_gen, "ref ")end 
table.insert(__text_gen, tostring(LocalName(parameter.Name)))end)
table.insert(__text_gen, ");\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(type, "gen_ret")))
table.insert(__text_gen, ";\r\n                    ")
local in_pos = 0ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1endif parameter.ParameterType.IsByRef thentable.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+1, LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
end
table.insert(__text_gen, "\r\n                    ")endend)table.insert(__text_gen, "\r\n\t\t\t\t\treturn ")
table.insert(__text_gen, tostring(out_num + 1))
table.insert(__text_gen, ";\r\n\t\t\t\t}\r\n\t\t\t\t")
end)if (not hasZeroParamsCtor) and type.IsValueType thentable.insert(__text_gen, "\r\n\t\t\t\tif (LuaAPI.lua_gettop(L) == 1)\r\n\t\t\t\t{\r\n\t\t\t\t    ")
table.insert(__text_gen, tostring(GetPushStatement(type, "default(" .. CsFullTypeName(type).. ")")))
table.insert(__text_gen, ";\r\n\t\t\t        return 1;\r\n\t\t\t\t}\r\n\t\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n            return LuaAPI.luaL_error(L, \"invalid arguments to ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, " constructor!\");\r\n            ")end 
table.insert(__text_gen, "\r\n        }\r\n        \r\n\t\t")if type.IsArray or ((indexers.Count or 0) > 0) then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __CSIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
if type.IsArray then 
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && LuaAPI.lua_isnumber(L, 2))\r\n\t\t\t\t{\r\n\t\t\t\t\tint index = (int)LuaAPI.lua_tonumber(L, 2);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(type:GetElementType(), "gen_to_be_invoked[index]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\treturn 2;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
elseif indexers.Count > 0 thentable.insert(__text_gen, "try {\r\n\t\t\t    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t\t")ForEachCsList(indexers, function(indexer)local paramter = indexer:GetParameters()[0]table.insert(__text_gen, "\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(paramter.ParameterType, 2)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(paramter.ParameterType, 2, "index", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(indexer.ReturnType, "gen_to_be_invoked[index]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\treturn 2;\r\n\t\t\t\t}\r\n\t\t\t\t")
end)
table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
end
table.insert(__text_gen, "\r\n            LuaAPI.lua_pushboolean(L, false);\r\n\t\t\treturn 1;\r\n        }\r\n\t\t")end 
table.insert(__text_gen, "\r\n        \r\n\t\t")
if type.IsArray or ((newindexers.Count or 0) > 0) then
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        public static int __NewIndexer(RealStatePtr L)\r\n        {\r\n\t\t\t")
if type.IsArray or newindexers.Count > 0 then 
table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if type.IsArray then local elementType = type:GetElementType()table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && LuaAPI.lua_isnumber(L, 2) && ")
table.insert(__text_gen, tostring(GetCheckStatement(elementType, 3)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\tint index = (int)LuaAPI.lua_tonumber(L, 2);\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(elementType, 3, "gen_to_be_invoked[index]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
elseif newindexers.Count > 0 then
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n\t\t\t\t")
ForEachCsList(newindexers, function(newindexer)local keyType = newindexer:GetParameters()[0].ParameterTypelocal valueType = newindexer:GetParameters()[1].ParameterTypetable.insert(__text_gen, "\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(type, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(keyType, 2)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(valueType, 3)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
if IsStruct(valueType) then
table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\tgen_to_be_invoked[key] = gen_value;")
elsetable.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_to_be_invoked[key]")))
table.insert(__text_gen, ";")
end
table.insert(__text_gen, "\r\n\t\t\t\t\tLuaAPI.lua_pushboolean(L, true);\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n\t\t\t\t")
end)
table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\tLuaAPI.lua_pushboolean(L, false);\r\n            return 1;\r\n        }\r\n\t\t")end 
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(operators, function(operator) 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int ")
table.insert(__text_gen, tostring(OpNameMap[operator.Name]))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n            ")if operator.Name ~= "op_UnaryNegation" and operator.Name ~= "op_OnesComplement"  then 
table.insert(__text_gen, "\r\n\t\t\ttry {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
ForEachCsList(operator.Overloads, function(overload)local left_param = overload:GetParameters()[0]local right_param = overload:GetParameters()[1]table.insert(__text_gen, "\r\n\t\t\t\r\n\t\t\t\tif (")
table.insert(__text_gen, tostring(GetCheckStatement(left_param.ParameterType, 1)))
table.insert(__text_gen, " && ")
table.insert(__text_gen, tostring(GetCheckStatement(right_param.ParameterType, 2)))
table.insert(__text_gen, ")\r\n\t\t\t\t{\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(left_param.ParameterType, 1, "leftside", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(right_param.ParameterType, 2, "rightside", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "leftside " .. OpCallNameMap[operator.Name] .. " rightside")))
table.insert(__text_gen, ";\r\n\t\t\t\t\t\r\n\t\t\t\t\treturn 1;\r\n\t\t\t\t}\r\n            ")
end)
table.insert(__text_gen, "\r\n\t\t\t}\r\n\t\t\tcatch(System.Exception gen_e) {\r\n\t\t\t\treturn LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n\t\t\t}\r\n            return LuaAPI.luaL_error(L, \"invalid arguments to right hand of ")
table.insert(__text_gen, tostring(OpCallNameMap[operator.Name]))
table.insert(__text_gen, " operator, need ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, "!\");\r\n            ")
else
table.insert(__text_gen, "\r\n\t\t\tObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            try {\r\n                ")
table.insert(__text_gen, tostring(GetCasterStatement(type, 1, "rightside", true)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetPushStatement(operator.Overloads[0].ReturnType, OpCallNameMap[operator.Name] .. " rightside")))
table.insert(__text_gen, ";\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n            return 1;\r\n            ")
end
table.insert(__text_gen, "\r\n        }\r\n        ")
end)
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(methods, function(method)
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _m_")
table.insert(__text_gen, tostring(method.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")local need_obj = not method.IsStaticif MethodCallNeedTranslator(method) thentable.insert(__text_gen, "\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n            ")
end
table.insert(__text_gen, "\r\n            ")
if need_obj then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n            ")
end
table.insert(__text_gen, "\r\n            ")
if method.Overloads.Count > 1 then
table.insert(__text_gen, "\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n            ")
end
table.insert(__text_gen, "\r\n                ")
ForEachCsList(method.Overloads, function(overload, oi)local parameters = MethodParameters(overload)local in_num = CalcCsList(parameters, function(p) return not (p.IsOut and p.ParameterType.IsByRef) end)local param_offset = method.IsStatic and 0 or 1local out_num = CalcCsList(parameters, function(p) return p.IsOut or p.ParameterType.IsByRef end)local in_pos = 0local has_return = (overload.ReturnType.FullName ~= "System.Void")local def_count = method.DefaultValues[oi]local param_count = parameters.Lengthlocal real_param_count = param_count - def_countlocal has_v_params = param_count > 0 and IsParams(parameters[param_count - 1])if method.Overloads.Count > 1 thentable.insert(__text_gen, "if(gen_param_count ")
table.insert(__text_gen, tostring(has_v_params and ">=" or "=="))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(in_num+param_offset-def_count - (has_v_params and 1 or 0)))ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endlocal parameterType = parameter.ParameterTypeif has_v_params and pi == param_count - 1 then  parameterType = parameterType:GetElementType() endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1; table.insert(__text_gen, "&& ")
table.insert(__text_gen, tostring(GetCheckStatement(parameterType , in_pos+param_offset, has_v_params and pi == param_count - 1)))end end)
table.insert(__text_gen, ") ")
end
table.insert(__text_gen, "\r\n                {\r\n                    ")
if overload.Name == "get_Item" and overload.IsSpecialName thenlocal keyType = overload:GetParameters()[0].ParameterType
table.insert(__text_gen, "\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_to_be_invoked[key]")))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
elseif overload.Name == "set_Item" and overload.IsSpecialName thenlocal keyType = overload:GetParameters()[0].ParameterTypelocal valueType = overload:GetParameters()[1].ParameterType
table.insert(__text_gen, "\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(keyType, 2, "key", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(GetCasterStatement(valueType, 3, "gen_value", true)))
table.insert(__text_gen, ";\r\n                    gen_to_be_invoked[key] = gen_value;\r\n                    ")elsein_pos = 0;ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1table.insert(__text_gen, tostring(GetCasterStatement(parameter.ParameterType, in_pos+param_offset, LocalName(parameter.Name), true, has_v_params and pi == param_count - 1)))else
table.insert(__text_gen, tostring(CsFullTypeName(parameter.ParameterType)))
table.insert(__text_gen, " ")
table.insert(__text_gen, tostring(LocalName(parameter.Name)))
end
table.insert(__text_gen, ";\r\n                    ")
end)
table.insert(__text_gen, "\r\n                    ")if has_return thentable.insert(__text_gen, "    var gen_ret = ")endif method.IsStatic thentable.insert(__text_gen, tostring(CsFullTypeName(type).."."..UnK(overload.Name)))elsetable.insert(__text_gen, "gen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(overload.Name)))end
table.insert(__text_gen, "( ")
ForEachCsList(parameters, function(parameter, pi) if pi >= real_param_count then return endif pi ~= 0 then 
table.insert(__text_gen, ", ")end; if parameter.IsOut and parameter.ParameterType.IsByRef then 
table.insert(__text_gen, "out ")elseif parameter.ParameterType.IsByRef and not parameter.IsIn then 
table.insert(__text_gen, "ref ")end 
table.insert(__text_gen, tostring(LocalName(parameter.Name)))end) 
table.insert(__text_gen, " );\r\n                    ")if has_return thentable.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetPushStatement(overload.ReturnType, "gen_ret")))
table.insert(__text_gen, ";\r\n                    ")endlocal in_pos = 0ForEachCsList(parameters, function(parameter, pi)if pi >= real_param_count then return endif not (parameter.IsOut and parameter.ParameterType.IsByRef) then in_pos = in_pos + 1endif parameter.ParameterType.IsByRef thentable.insert(__text_gen, tostring(GetPushStatement(parameter.ParameterType:GetElementType(), LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
if not parameter.IsOut and parameter.ParameterType.IsByRef and NeedUpdate(parameter.ParameterType) then table.insert(__text_gen, tostring(GetUpdateStatement(parameter.ParameterType:GetElementType(), in_pos+param_offset, LocalName(parameter.Name))))
table.insert(__text_gen, ";\r\n                        ")
end
table.insert(__text_gen, "\r\n                    ")endend)endtable.insert(__text_gen, "\r\n                    ")
if NeedUpdate(type) and not method.IsStatic then
table.insert(__text_gen, "\r\n                        ")
table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
table.insert(__text_gen, ";\r\n                    ")
end
table.insert(__text_gen, "\r\n                    \r\n                    return ")
table.insert(__text_gen, tostring(out_num+(has_return and 1 or 0)))
table.insert(__text_gen, ";\r\n                }\r\n                ")end)
table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n            ")
if method.Overloads.Count > 1 then
table.insert(__text_gen, "\r\n            return LuaAPI.luaL_error(L, \"invalid arguments to ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(method.Overloads[0].Name))
table.insert(__text_gen, "!\");\r\n            ")
end
table.insert(__text_gen, "\r\n        }\r\n        ")end)
table.insert(__text_gen, "\r\n        \r\n        \r\n        ")
ForEachCsList(getters, function(getter) if getter.IsStatic and getter.ReadOnly then return end --readonly statictable.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _g_get_")
table.insert(__text_gen, tostring(getter.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n            ")
if AccessorNeedTranslator(getter) then 
table.insert(__text_gen, "    ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if not getter.IsStatic then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetPushStatement(getter.Type, "gen_to_be_invoked."..UnK(getter.Name))))
table.insert(__text_gen, ";")else 
table.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetPushStatement(getter.Type, CsFullTypeName(type).."."..UnK(getter.Name))))
table.insert(__text_gen, ";")end
table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n            return 1;\r\n        }\r\n        ")
end)
table.insert(__text_gen, "\r\n        \r\n        ")
ForEachCsList(setters, function(setter)local is_struct = IsStruct(setter.Type)table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _s_set_")
table.insert(__text_gen, tostring(setter.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ")
if AccessorNeedTranslator(setter) then 
table.insert(__text_gen, "ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);")
end
table.insert(__text_gen, "\r\n\t\t\t")
if not setter.IsStatic then 
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
if is_struct then 
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\tgen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(setter.Name)))
table.insert(__text_gen, " = gen_value;")else table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 2, "gen_to_be_invoked." .. UnK(setter.Name))))
table.insert(__text_gen, ";")
endelse if is_struct then 
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, "gen_value", true)))
table.insert(__text_gen, ";\r\n\t\t\t\t")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(setter.Name)))
table.insert(__text_gen, " = gen_value;")
elsetable.insert(__text_gen, "    ")
table.insert(__text_gen, tostring(GetCasterStatement(setter.Type, 1, CsFullTypeName(type) .."." .. UnK(setter.Name))))
table.insert(__text_gen, ";")
endend
table.insert(__text_gen, "\r\n            ")
if NeedUpdate(type) and not setter.IsStatic then
table.insert(__text_gen, "\r\n                ")
table.insert(__text_gen, tostring(GetUpdateStatement(type, 1, "gen_to_be_invoked")))
table.insert(__text_gen, ";\r\n            ")
end
table.insert(__text_gen, "\r\n            } catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n            return 0;\r\n        }\r\n        ")
end)
table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
ForEachCsList(events, function(event) if not event.IsStatic then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n\t\t\t")
table.insert(__text_gen, tostring(GetSelfStatement(type)))
table.insert(__text_gen, ";\r\n                ")
table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 3, "gen_delegate", true)))
table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, \"#3 need ")
table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
table.insert(__text_gen, "!\");\r\n                }\r\n\t\t\t\t\r\n\t\t\t\tif (gen_param_count == 3)\r\n\t\t\t\t{\r\n\t\t\t\t\t")
if event.CanAdd then
table.insert(__text_gen, "\r\n\t\t\t\t\tif (LuaAPI.xlua_is_eq_str(L, 2, \"+\")) {\r\n\t\t\t\t\t\tgen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(event.Name)))
table.insert(__text_gen, " += gen_delegate;\r\n\t\t\t\t\t\treturn 0;\r\n\t\t\t\t\t} \r\n\t\t\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\t\t\t")
if event.CanRemove then
table.insert(__text_gen, "\r\n\t\t\t\t\tif (LuaAPI.xlua_is_eq_str(L, 2, \"-\")) {\r\n\t\t\t\t\t\tgen_to_be_invoked.")
table.insert(__text_gen, tostring(UnK(event.Name)))
table.insert(__text_gen, " -= gen_delegate;\r\n\t\t\t\t\t\treturn 0;\r\n\t\t\t\t\t} \r\n\t\t\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\t\t}\r\n\t\t\t} catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n\t\t\tLuaAPI.luaL_error(L, \"invalid arguments to ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "!\");\r\n            return 0;\r\n        }\r\n        ")
end end)
table.insert(__text_gen, "\r\n\t\t\r\n\t\t")
ForEachCsList(events, function(event) if event.IsStatic then 
table.insert(__text_gen, "\r\n        [MonoPInvokeCallbackAttribute(typeof(LuaCSFunction))]\r\n        static int _e_")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "(RealStatePtr L)\r\n        {\r\n\t\t    try {\r\n                ObjectTranslator translator = ObjectTranslatorPool.Instance.Find(L);\r\n\t\t\t    int gen_param_count = LuaAPI.lua_gettop(L);\r\n                ")
table.insert(__text_gen, tostring(GetCasterStatement(event.Type, 2, "gen_delegate", true)))
table.insert(__text_gen, ";\r\n                if (gen_delegate == null) {\r\n                    return LuaAPI.luaL_error(L, \"#2 need ")
table.insert(__text_gen, tostring(CsFullTypeName(event.Type)))
table.insert(__text_gen, "!\");\r\n                }\r\n                \r\n\t\t\t\t")
if event.CanAdd then
table.insert(__text_gen, "\r\n\t\t\t\tif (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, \"+\")) {\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(event.Name)))
table.insert(__text_gen, " += gen_delegate;\r\n\t\t\t\t\treturn 0;\r\n\t\t\t\t} \r\n\t\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\t\t")
if event.CanRemove then
table.insert(__text_gen, "\r\n\t\t\t\tif (gen_param_count == 2 && LuaAPI.xlua_is_eq_str(L, 1, \"-\")) {\r\n\t\t\t\t\t")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(UnK(event.Name)))
table.insert(__text_gen, " -= gen_delegate;\r\n\t\t\t\t\treturn 0;\r\n\t\t\t\t} \r\n\t\t\t\t")
end
table.insert(__text_gen, "\r\n\t\t\t} catch(System.Exception gen_e) {\r\n                return LuaAPI.luaL_error(L, \"c# exception:\" + gen_e);\r\n            }\r\n\t\t\treturn LuaAPI.luaL_error(L, \"invalid arguments to ")
table.insert(__text_gen, tostring(CsFullTypeName(type)))
table.insert(__text_gen, ".")
table.insert(__text_gen, tostring(event.Name))
table.insert(__text_gen, "!\");\r\n        }\r\n        ")
end end)
table.insert(__text_gen, "\r\n    }\r\n}\r\n")
return table.concat(__text_gen)
到这里看到模板在内存中对应变成了一个生成的方法,对应传进C#的替换字符。

替换比较复杂不一一分析了。大概就是C#对应类的成员变量,静态方法等所有元数据替换成table的表里,一个循环遍历进行插入字符比如下面的GameObject的构造函数

相关文章:

Xlua原理 二

一已经介绍了初步的lua与C#通信的原理&#xff0c;和xlua的LuaEnv的初始化内容。 这边介绍下Wrap文件。 一.Wrap介绍 导入xlua后可以看到会多出上图菜单。 点击后生成一堆wrap文件&#xff0c;这些文件是lua调用C#时进行映射查找用的中间代码。这样就不需要去反射调用节约性…...

《数据结构》--顺序表

C语言语法基础到数据结构与算法&#xff0c;前面已经掌握并具备了扎实的C语言基础&#xff0c;为什么要学习数据结构课程&#xff1f;--我们学完本章就可以实践一个&#xff1a;通讯录项目 简单了解过后&#xff0c;通讯录具备增加、删除、修改、查找联系人等操作。要想实现通…...

Qt:愚蠢的qmake

博主参与了一个使用qmake构建的项目&#xff0c;包含几百个源文件&#xff0c;最近遇到一个恼人的问题&#xff1a;有时仅仅修改了一个.cpp文件&#xff0c;构建项目时就有可能触发全编译。但是编译时又会命中ccache的缓存&#xff0c;这说明源代码实际上内容并没有发生变化。即…...

Apache Dubbo:分布式服务框架的深度解析

文章目录 引言官网链接Dubbo 原理架构概览通信协议负载均衡 基础使用1. 引入依赖2. 配置服务提供者3. 配置服务消费者4. 配置注册中心 高级使用1. 集群容错2. 泛化引用3. 异步调用 优缺点优点缺点 结论 引言 Apache Dubbo 是一个高性能、轻量级的开源 Java RPC 框架。它提供了…...

【前端学习】CSS三大特性

CSS三大特性 CSS的三大特性是为了化简代码、定位问题并且解决问题 继承性 继承性特点&#xff1a; 子级默认继承父级的文字控制属性。注意&#xff1a;如果标签自己有样式则生效自己的样式&#xff0c;不继承。 <!DOCTYPE html> <html lang"en"><…...

了解网络是如何运作

“Web 的工作原理”提供了一个简化的视图,用于了解在计算机或手机上的 Web 浏览器中查看网页时发生的情况。 这个理论对于短期内编写 Web 代码来说并不是必需的,但不久之后,你就会真正开始从理解后台发生的事情中受益。 客户端和服务器 连接到 Internet 的计算机称为客户端和…...

传输层协议——TCP

TCP协议 TCP全称为“传输控制协议”&#xff0c;要对数据的传输进行一个详细的控制。 特点 面向连接的可靠性字节流 TCP的协议段格式 源/目的端口&#xff1a;表示数据从哪个进程来&#xff0c;到哪个进程4位首部长度&#xff1a;表示该TCP头部有多少字节&#xff08;注意它…...

C++相关概念和易错语法(23)(set、仿函数的应用、pair、multiset)

1.set和map存在的意义 &#xff08;1&#xff09;set和map的底层都是二叉搜索树&#xff0c;可以达到快速排序&#xff08;当我们按照迭代器的顺序来遍历set和map&#xff0c;其实是按照中序来遍历的&#xff0c;是排过序的&#xff09;、去重、搜索的目的。 &#xff08;2&a…...

netty入门-3 EventLoop和EventLoopGroup,简单的服务器实现

文章目录 EventLoop和EventLoopGroup服务器与客户端基本使用增加非NIO工人NioEventLoop 处理普通任务与定时任务 结语 EventLoop和EventLoopGroup 二者大概是什么这里不再赘述&#xff0c;前一篇已简述过。 不理解也没关系。 下面会简单使用&#xff0c;看了就能明白是什么 这…...

通信原理-思科实验五:家庭终端以太网接入Internet实验

实验五 家庭终端以太网接入Internet实验 一实验内容 二实验目的 三实验原理 四实验步骤 1.按照上图选择对应的设备&#xff0c;并连接起来 为路由器R0两个端口配置IP 为路由器R1端口配置IP 为路由器设备增加RIP&#xff0c;配置接入互联网的IP的动态路由项 5.为路由器R1配置静…...

【Vue】vue概述

1、简介 Vue.js&#xff08;简称Vue&#xff09;是一款用于构建用户界面的渐进式JavaScript框架。由前Google高级软件工程师尤雨溪&#xff08;Evan You&#xff09;于2014年创建&#xff0c;是一个独立且社区驱动的开源项目。Vue.js基于标准的HTML、CSS和JavaScript&#xff…...

Docker use experience

#docker command docker load -i <镜像文件.tar> docker run -it -d --name 容器名 -p 宿主机端口:容器端口 -v 宿主机文件存储位置:容器内文位置 镜像名:Tag /bin/bash docker commit -m"提交的描述信息" -a"作者" 容器ID 要…...

Android平台RTSP|RTMP直播播放器技术接入说明

技术背景 大牛直播SDK自2015年发布RTSP、RTMP直播播放模块&#xff0c;迭代从未停止&#xff0c;SmartPlayer功能强大、性能强劲、高稳定、超低延迟、超低资源占用。无需赘述&#xff0c;全自研内核&#xff0c;行业内一致认可的跨平台RTSP、RTMP直播播放器。本文以Android平台…...

数据结构——栈(顺序结构)

一、栈的定义 栈是一种数据结构&#xff0c;它是一种只能在一端进行插入和删除操作的特殊线性表。这一端被称为栈顶&#xff0c;另一端被称为栈底。栈按照后进先出&#xff08;LIFO&#xff09;的原则进行操作&#xff08;类似与手枪装弹后射出子弹的顺序&#xff09;。在计算…...

速盾:cdn能防御ddos吗?

CDN&#xff08;内容分发网络&#xff09;是一种广泛应用于互联网中的技术&#xff0c;它通过将内容分发到全球各地的服务器上&#xff0c;以提高用户在访问网站时的加载速度和稳定性。然而&#xff0c;CDN是否能够有效防御DDoS&#xff08;分布式拒绝服务&#xff09;攻击是一…...

分享 2 个 .NET EF 6 只更新某些字段的方法

前言 EF 更新数据时&#xff0c;通常情况下&#xff0c;是更新全部字段的&#xff0c;但实际业务中&#xff0c;更新全部字段的情况其实很少&#xff0c;一般都是修改其中某些字段&#xff0c;所以为了实现这个目标&#xff0c;很多程序员通常会这样作&#xff1a; 先从数据库…...

vs code解决报错 (c/c++的配置环境 远端机器为Linux ubuntu)

参考链接&#xff1a;https://blog.csdn.net/fightfightfight/article/details/82857397 https://blog.csdn.net/m0_38055352/article/details/105375367 可以按照步骤确定那一步不对&#xff0c;如果一个可以就不用往下看了 目录 一、检查一下文件扩展名 二、安装扩展包并…...

08 字符串和字节串

使用单引号、双引号、三单引号、三双引号作为定界符&#xff08;delimiter&#xff09;来表示字符串&#xff0c;并且不同的定界符之间可以相互嵌套。 很多内置函数和标准库对象也都支持对字符串的操作。 x hello world y Python is a great language z Tom said, "Le…...

vue使用mavonEditor(流程图、时序图、甘特图实现)

mavonEditor 安装mavonEditor $ npm install mavon-editor --save使用 // 全局注册import Vue from vueimport mavonEditor from mavon-editorimport mavon-editor/dist/css/index.css// useVue.use(mavonEditor)new Vue({el: #main,data() {return { value: }}})//局部使用…...

Java实现短信验证码服务

1.首先这里使用的是阿里云的短信服务。 package com.wzy.util;; import cn.hutool.captcha.generator.RandomGenerator; import com.aliyun.dysmsapi20170525.Client; import com.wzy.entity.Ali; import org.springframework.stereotype.Component;/*** Author: 顾安* Descri…...

python中的线程

线程 线程概念 线程 在一个进程的内部, 要同时干多件事, 就需要同时运行多个"子任务", 我们把进程内的这些"子任务"叫做线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中, 是进程的实际运作单位。一条线程指的是进程中一个单一顺序的控制流…...

hcip学习 多实例生成树,VRRP工作原理

一、STP 和 RSTP 解决了什么问题 1、STP&#xff1a;解决了在冗余的二层网络中所出现的环路问题 2、RSTP&#xff1a;在 STP 的基础上&#xff0c;解决了 STP 收敛速度慢的问题&#xff0c;引入了一些 STP 保护机制&#xff0c;使其网络更加稳定 二、MSTP 针对 RSTP 的改进 …...

Docker搭建群晖

Docker搭建群晖 本博客介绍在docker下搭建群晖 1.编辑docker-compose.yml文件 version: "3" services:dsm:container_name: dsmimage: vdsm/virtual-dsm:latestenvironment:DISK_SIZE: "16G"cap_add:- NET_ADMIN ports:- 8080:50…...

【java】BIO,NIO,多路IO复用,AIO

在Java中&#xff0c;处理I/O操作的模型主要有四种&#xff1a;阻塞I/O (BIO), 非阻塞I/O (NIO), 异步I/O (AIO), 以及IO多路复用。下面详细介绍这四种I/O模型的工作原理和应用场景。 1. 阻塞I/O (BIO) 工作原理 阻塞I/O是最传统的I/O模型。在这种模型中&#xff0c;当一个线…...

服务器怎样减少带宽消耗的问题?

择业在使用服务器的过程中会消耗大量的带宽资源&#xff0c;而减少服务器的带宽消耗则可以帮助企业降低经济成本&#xff0c;同时还能够提高用户的访问速度&#xff0c;那么服务器怎样能减少带宽的消耗呢&#xff1f;本文就来带领大家一起来探讨一下吧&#xff01; 企业可以选择…...

linux 报错:bash: /etc/profile: 行 32: 语法错误:未预期的文件结束符

目录 注意错误不一定错在最后一行 i进入编辑 esc退出编辑 &#xff1a;wq 保存编辑退出 &#xff1a;q&#xff01;不保存退出 if [ $# -eq 3 ] then if [ ! -e "$1" ]; then miss1 $1 elif [ ! -e "$2" -a ! -e "$3" ]; then miss2and3…...

MySQL练习(5)

作业要求&#xff1a; 实现过程&#xff1a; 一、触发器 &#xff08;1&#xff09;建立两个表&#xff1a;goods&#xff08;商品表&#xff09;、orders&#xff08;订单表&#xff09; &#xff08;2&#xff09;在商品表中导入商品记录 &#xff08;3&#xff09;建立触发…...

泛型新理解

1.创建三个类&#xff0c;并写好对应关系 package com.jmj.gulimall.study;public class People { }package com.jmj.gulimall.study;public class Student extends People{ }package com.jmj.gulimall.study;public class Teacher extends People{ }2.解释一下这三个方法 pub…...

JavaSE--基础语法--继承和多态(第三期)

一.继承 1.1我们为什么需要继承? 首先&#xff0c;Java中使用类对现实世界中实体来进行描述&#xff0c;类经过实例化之后的产物对象&#xff0c;则可以用来表示现实中的实体&#xff0c;但是 现实世界错综复杂&#xff0c;事物之间可能会存在一些关联&#xff0c;那在设计程…...

高级java每日一道面试题-2024年7月23日-什么时候用包装类, 什么时候用原始类

面试官: 你在什么时候用包装类, 什么时候用原始类? 我回答: 在Java开发中&#xff0c;理解何时使用包装类&#xff08;Wrapper Classes&#xff09;和何时使用原始类&#xff08;Primitive Types&#xff09;是非常重要的。这主要取决于你的具体需求以及Java语言本身的一些限…...