当前位置: 首页 > 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语言本身的一些限…...

LINUX之MMC子系统分析

目录 1. 概念1.1 MMC卡1.2 SD卡1.3 SDIO 2. 总线协议2.1 协议2.2 一般协议2.3 写数据2.4 读数据2.5 卡模式2.5.1 SD卡模式2.5.2 eMMC模式 2.6 命令2.6.1 命令类2.6.2 详细命令 2.7 应答2.8 寄存器2.8.1 OCR2.8.2 CID2.8.3 CSD2.8.4 RCA2.8.5 扩展CSD 3. 关键结构3.1 struct sdh…...

VulnHub:cengbox1

靶机下载地址&#xff0c;下载完成后&#xff0c;用VirtualBox打开靶机并修改网络为桥接即可搭建成功。 信息收集 主机发现和端口扫描 扫描攻击机&#xff08;192.168.31.218&#xff09;同网段存活主机确认目标机ip&#xff0c;并对目标机进行全面扫描。 nmap 192.168.31.…...

MySQL第一阶段:多表查询、事务

继续我的MySQL之旅&#xff0c;继续上篇的DDL、DML、DQL、以及一些约束&#xff0c;该到了多表查询和事务的学习总结&#xff0c;以及相关的案例实现&#xff0c;为未来的复习以及深入的理解做好知识储备。 目录 多表查询 连接查询 内连接 外连接 子查询 事务 事务简介…...

Java的序列化和反序列化

序列化&#xff1a; 将数据结构或对象转换成二进制串的过程 反序列化&#xff1a;将在序列化过程中所生成的二进制串转换成数据结构或者对象的过程 至于为什么要序列化和反序列化呢&#xff1f; 因为互联网的产生带来了机器间通讯的需求&#xff0c;而互联通讯的双方需要采用约…...

本地连接远程阿里云K8S

1.首先安装kubectl 1.1验证自己系统 uname -m 1.2 按照步骤安装 在 Linux 系统中安装并设置 kubectl | Kubernetes 1.3 阿里云配置 通过kubectl连接Kubernetes集群_容器服务 Kubernetes 版 ACK(ACK)-阿里云帮助中心 2.验证 阿里云config直接导出&#xff0c;直接扔到.…...

CasaOS设备使用Docker安装SyncThing文件同步神器并实现远程管理

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

k210 图像操作详解(一)(直线检测、边缘检测、色块追踪)

1、直线检测 ##################################################################################################### # file main.py # author 正点原子团队(ALIENTEK) # version V1.0 # date 2024-01-17 # brief image图像特征检测实…...

【Java版数据结构】初识泛型

看到这句话的时候证明&#xff1a;此刻你我都在努力 加油陌生人 br />个人主页&#xff1a;Gu Gu Study专栏&#xff1a;Java版数据结构 喜欢的一句话&#xff1a; 常常会回顾努力的自己&#xff0c;所以要为自己的努力留下足迹 喜欢的话可以点个赞谢谢了。 作者&#xff1…...

DevExpress WinForms自动表单布局,创建高度可定制用户体验(二)

使用DevExpress WinForms的表单布局组件可以创建高度可定制的应用程序用户体验&#xff0c;从自动安排UI控件到按比例调整大小&#xff0c;DevExpress布局和数据布局控件都可以让您消除与基于像素表单设计相关的麻烦。 P.S&#xff1a;DevExpress WinForms拥有180组件和UI库&a…...

vue中v-if和v-for

vue中v-if和v-for Vue 官方建议不要在同一个元素上同时使用 v-if 和 v-for 指令&#xff0c;主要有以下几个原因&#xff1a; 性能问题&#xff1a; 当 v-if 和 v-for 一起使用时&#xff0c;Vue 在每次渲染时都需要先执行循环&#xff0c;然后再对每个元素进行条件判断。这可能…...

【MySQL】根据binlog日志获取回滚sql的一个开发思路

根据binlog日志获取回滚sql的一个开发思路 需要获取的信息 thread_id 打开 mysql 客户端 开始时间 关闭 mysql 客户端 结束时间 binlog 匹配流程 指定 mysql 客户端 开始时间和结束时间 先匹配 thread_id 相同的 然后匹配 ^BEGIN$行和 ^COMMIT/*!*/;$行之间的数据 当匹…...

Kafka快速入门+SpringBoot简单的秒杀案例

1. 主题相关 1.1 创建主题 kafka-topics.sh --create --bootstrap-server [服务器地址] --replication-factor [副本数] --partitions [分区数] --topic [主题名]liberliber-VMware-Virtual-Platform:/home/zookeeper$ docker-compose exec kafka /bin/bash #进入kafka容器 b…...

Redis哨兵机制

哨兵机制&#xff1a; &#xff08;1&#xff09;监控&#xff1a;有一个哨兵集群&#xff0c;这个哨兵集群检测redis的主从集群。它是每隔1秒钟就向主从集群中的节点发送心跳&#xff0c;如果节点没有回复&#xff0c;则这个哨兵就主观的认为这个节点发生故障&#xff0c;这时…...

OSPF概述

OSPF OSPF属于内部网关路由协议【IGP】 用于单一自治系统【Autonomous System-AS】内决策路由 自治系统【AS】 执行统一路由策略的一组网络设备的组合 OSPF概述 为了适应大型的网络&#xff0c;OSPF在AS内划分多个区域 每个OSPF路由器只维护所在区域的完整的链路状态信息 …...

CSS学习笔记[Web开发]

CSS学习 本文为学习笔记&#xff0c;参考菜鸟和w3c 文章目录 CSS 简介CSS 插入外部 CSS内部 CSS行内 CSS多个样式表层叠顺序 CSS 语法例子解释 CSS 选择器CSS 元素选择器CSS id 选择器实例CSS 类选择器实例CSS 通用选择器实例CSS 分组选择器CSS 后代选择器CSS 子元素选择器CSS …...

Go基础编程 - 11 - 函数(func)

接口&#xff08;interface&#xff09; 函数1. 函数定义1.1. 函数名1.2. 参数列表1.3. 返回值列表 2. 匿名函数3. 闭包、递归3.1 闭包3.1.1 函数、引用环境3.1.2 闭包的延迟绑定3.1.3 goroutine 的延迟绑定 3.2 递归函数 4. 延迟调用&#xff08;defer&#xff09;4.1 defer特…...

Typora入门

标题&#xff08;clrt数字&#xff09; 段落 实现换行 1.在一个行的结尾加上两个空格实现换行 2.在两行之间加上空行实现换行 实现分割线 &#xff08;1.***三个星号实现分割线&#xff09; (2.三个以上的—也可以实现分割线) 强调 斜体&#xff1a;我是斜体 (单下划线…...

PT2262-IR

PT2262是一款很古老的编码芯片&#xff0c;其兼容型号有&#xff1a;SC2262&#xff0c;AD2262&#xff0c;SC2260(需改变匹配电阻)等。 依据其datasheet&#xff0c;PT2262射频模式工作原理: CODE BITS A Code Bit is the basic component of the encoded waveform, and ca…...

JavaScript 迭代器

在JavaScript中&#xff0c;迭代器是一种允许我们遍历集合中元素的对象。迭代器对象具有一个next()方法&#xff0c;该方法返回value和done。value是当前迭代的值&#xff0c;done属性是一个布尔值&#xff0c;表示是否到达了集合的末尾。 迭代器协议 一个迭代器对象必须具备以…...

数据结构之《队列》

在数据结构之《栈》章节中学习了线性表中除了顺序表和链表外的另一种结构——栈&#xff0c;在本篇中我们将继续学习另一种线性表的结构——队列&#xff0c;在通过本篇的学习后&#xff0c;你将会对栈的结构有充足的了解&#xff0c;在了解完结构后我们还将进行栈的实现。一起…...