当前位置: 首页>>代码示例>>C#>>正文


C# ILProcessor.Append方法代码示例

本文整理汇总了C#中Mono.Cecil.Cil.ILProcessor.Append方法的典型用法代码示例。如果您正苦于以下问题:C# ILProcessor.Append方法的具体用法?C# ILProcessor.Append怎么用?C# ILProcessor.Append使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在Mono.Cecil.Cil.ILProcessor的用法示例。


在下文中一共展示了ILProcessor.Append方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C#代码示例。

示例1: Generate

 public override void Generate(ILProcessor processor)
 {
     // Now add the IL that creates the delegate.
     processor.Append(Instruction.Create(OpCodes.Nop));
     processor.Append(Instruction.Create(OpCodes.Ldarg_0));
     processor.Append(Instruction.Create(OpCodes.Ldftn, this.m_Target));
     //processor.Append(Instruction.Create(OpCodes.Ldnull));
     processor.Append(Instruction.Create(OpCodes.Newobj, this.m_Constructor));
     processor.Append(Instruction.Create(OpCodes.Stloc, this.m_Storage));
 }
开发者ID:hach-que,项目名称:Dx,代码行数:10,代码来源:InitDelegateStatement.cs

示例2: Generate

        public override void Generate(ILProcessor processor)
        {
            // Load the arguments.
            foreach (VariableDefinition v in m_Parameters)
            {
                processor.Append(Instruction.Create(OpCodes.Ldloc, v));
            }

            // Call the delegate.
            processor.Append(Instruction.Create(OpCodes.Call, this.m_Target));

            // Handle the return type.
            if (this.m_ReturnType.FullName == this.m_Target.Module.Import(typeof(void)).FullName)
            {
                // Return value is void.  Discard any result and return.
                processor.Append(Instruction.Create(OpCodes.Pop));
            }
            else if (this.m_ReturnType.IsValueType || this.m_ReturnType.IsGenericParameter)
            {
                // Return value is value type (not reference).  Unbox and return it.
                processor.Append(Instruction.Create(OpCodes.Unbox_Any, this.m_ReturnType));
                processor.Append(Instruction.Create(OpCodes.Stloc, this.Result));
            }
            else
            {
                // Return value is reference type.  Cast it and return it.
                processor.Append(Instruction.Create(OpCodes.Isinst, this.m_ReturnType));
                processor.Append(Instruction.Create(OpCodes.Stloc, this.Result));
            }
        }
开发者ID:hach-que,项目名称:Dx,代码行数:30,代码来源:CallStatement.cs

示例3: FillResetWatchdog

        private void FillResetWatchdog(ILProcessor ilProc)
        {
            Instruction ldarg = Instruction.Create(OpCodes.Ldarg_0);

            FieldReference targetField = new FieldReference("_computerTarget", GetCommonTingComputer(), _target);
            Instruction targetToStack = Instruction.Create(OpCodes.Ldfld, targetField);

            MethodReference injectoid = _source.Methods.First(o => o.Name == "ResetWatchdog");
            injectoid = _target.Module.Import(injectoid);
            Instruction callInjectoid = Instruction.Create(OpCodes.Call, injectoid);

            Instruction ret = Instruction.Create(OpCodes.Ret);

            ilProc.Append(ldarg);
            ilProc.Append(targetToStack);
            ilProc.Append(callInjectoid);
            ilProc.Append(ret);
        }
开发者ID:Itaros,项目名称:EHBExtendedAPI,代码行数:18,代码来源:InjectScrewdriverAPI.cs

示例4: ImplementProceed

            protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode)
            {
                // If T is an interface, then we want to check if target is null; if so, we want to just return the default value
                var targetNotNull = il.Create(OpCodes.Nop);
                EmitProxyFromProceed(il);
                il.Emit(OpCodes.Ldfld, ClassWeaver.Target);  // Load "target" from "this"
                il.Emit(OpCodes.Brtrue, targetNotNull);      // If target is not null, jump below
                CecilExtensions.CreateDefaultMethodImplementation(methodBody.Method, il);

                il.Append(targetNotNull);                    // Mark where the previous branch instruction should jump to                        

                base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
            }
开发者ID:kswoll,项目名称:sexy-proxy,代码行数:13,代码来源:InterfaceClassWeaver.cs

示例5: Initialize

        /// <summary>
        /// Emits the instructions that call <see cref="IInitialize.Initialize"/> on a given service instance.
        /// </summary>
        /// <param name="il"></param>
        /// <param name="module">The host module.</param>
        /// <param name="serviceInstance">The local variable that points to the current service instance.</param>
        public void Initialize(ILProcessor il, ModuleDefinition module, VariableDefinition serviceInstance)
        {
            var body = il.Body;
            var method = body.Method;
            var declaringType = method.DeclaringType;

            var targetField = GetTargetField(declaringType);
            if (targetField == null)
                return;

            var initializeType = module.ImportType<IInitialize>();

            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);

            var initializeMethod = module.ImportMethod<IInitialize>("Initialize");
            var skipInitializationCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Brfalse, skipInitializationCall);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);

            var containsMethod = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Callvirt, containsMethod);
            il.Emit(OpCodes.Brtrue, skipInitializationCall);

            // if (!__initializedServices.ContainsKey(currentService.GetHashCode()) {
            il.Emit(OpCodes.Ldloc, serviceInstance);
            il.Emit(OpCodes.Isinst, initializeType);
            il.Emit(OpCodes.Ldarg_0);

            il.Emit(OpCodes.Callvirt, initializeMethod);

            // __initializedServices.Add(hashCode, 0);
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, targetField);
            GetServiceHash(il, module, serviceInstance);
            il.Emit(OpCodes.Ldc_I4_1);

            var addMethod = module.ImportMethod<Dictionary<int, int>>("Add");
            il.Emit(OpCodes.Callvirt, addMethod);

            il.Append(skipInitializationCall);
        }
开发者ID:philiplaureano,项目名称:Hiro,代码行数:51,代码来源:ServiceInitializer.cs

示例6: ImplementProceed

            protected override void ImplementProceed(MethodDefinition methodInfo, MethodBody methodBody, ILProcessor il, FieldReference methodInfoField, MethodReference proceed, Action<ILProcessor> emitProceedTarget, MethodReference proceedTargetMethod, OpCode proceedOpCode)
            {
                if (methodInfo.IsAbstract)
                {
                    CecilExtensions.CreateDefaultMethodImplementation(methodInfo, il);
                }
                else
                {
                    var targetNotNull = il.Create(OpCodes.Nop);
                    EmitProxyFromProceed(il);
                    il.Emit(OpCodes.Ldfld, target);              // Load "target" from "this"
                    il.Emit(OpCodes.Brtrue, targetNotNull);      // If target is not null, jump below

                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, _ => EmitProxyFromProceed(il), callBaseMethod, OpCodes.Call);

                    il.Append(targetNotNull);                    // Mark where the previous branch instruction should jump to                        
                
                    base.ImplementProceed(methodInfo, methodBody, il, methodInfoField, proceed, emitProceedTarget, proceedTargetMethod, proceedOpCode);
                }
            }
开发者ID:kswoll,项目名称:sexy-proxy,代码行数:20,代码来源:NonInterfaceClassWeaver.cs

示例7: EmitCpblk

 /// <summary>
 /// Emits the cpblk method, supporting x86 and x64 platform.
 /// </summary>
 /// <param name="method">The method.</param>
 /// <param name="gen">The gen.</param>
 private void EmitCpblk(MethodDefinition method, ILProcessor gen)
 {
     var cpblk = gen.Create(OpCodes.Cpblk);
     //gen.Emit(OpCodes.Sizeof, voidPointerType);
     //gen.Emit(OpCodes.Ldc_I4_8);
     //gen.Emit(OpCodes.Bne_Un_S, cpblk);
     gen.Emit(OpCodes.Unaligned, (byte)1);       // unaligned to 1
     gen.Append(cpblk);
     
 }
开发者ID:RecursiveCall,项目名称:SharpDX,代码行数:15,代码来源:InteropApp.cs

示例8: EmitParameters


//.........这里部分代码省略.........
                    il.Emit(OpCodes.Conv_I);
                }
                else if (p.IsArray)
                {
                    if (p.Name != method.Module.Import(typeof(string[])).Name)
                    {
                        // .Net treats 1d arrays differently than higher rank arrays.
                        // 1d arrays are directly supported by instructions such as ldlen and ldelema.
                        // Higher rank arrays must be accessed through System.Array methods such as get_Length.
                        // 1d array:
                        //    check array is not null
                        //    check ldlen array > 0
                        //    ldc.i4.0
                        //    ldelema
                        // 2d array:
                        //    check array is not null
                        //    check array.get_Length() > 0
                        //    ldc.i4.0
                        //    ldc.i4.0
                        //    call instance T& T[0..., 0...]::Address(int32, int32)
                        // Mono treats everything as a 1d array.
                        // Interestingly, the .Net approach works on both Mono and .Net.
                        // The Mono approach fails when using high-rank arrays on .Net.
                        // We should report a bug to http://bugzilla.xamarin.com

                        // Pin the array and pass the address
                        // of its first element.
                        var array = (ArrayType)p;
                        var element_type = p.GetElementType();
                        body.Variables.Add(new VariableDefinition(new PinnedType(new ByReferenceType(element_type))));
                        int pinned_index = body.Variables.Count - 1;

                        var empty = il.Create(OpCodes.Ldc_I4, 0);
                        var pin = il.Create(OpCodes.Ldarg, i);
                        var end = il.Create(OpCodes.Stloc, pinned_index);

                        // if (array == null) goto empty
                        il.Emit(OpCodes.Brfalse, empty);

                        // else if (array.Length != 0) goto pin
                        il.Emit(OpCodes.Ldarg, i);
                        if (array.Rank == 1)
                        {
                            il.Emit(OpCodes.Ldlen);
                            il.Emit(OpCodes.Conv_I4);
                        }
                        else
                        {
                            var get_length = method.Module.Import(
                                mscorlib.MainModule.GetType("System.Array").Methods.First(m => m.Name == "get_Length"));
                            il.Emit(OpCodes.Callvirt, get_length);
                        }
                        il.Emit(OpCodes.Brtrue, pin);

                        // empty: IntPtr ptr = IntPtr.Zero
                        il.Append(empty);
                        il.Emit(OpCodes.Conv_U);
                        il.Emit(OpCodes.Br, end);

                        // pin: &array[0]
                        il.Append(pin);
                        if (array.Rank == 1)
                        {
                            // 1d array (vector), address is taken by ldelema
                            il.Emit(OpCodes.Ldc_I4, 0);
                            il.Emit(OpCodes.Ldelema, element_type);
                        }
                        else
                        {
                            // 2d-3d array, address must be taken as follows:
                            // call instance T& T[0..., 0..., 0...]::Address(int, int, int)
                            ByReferenceType t_ref = array.ElementType.MakeByReferenceType();
                            MethodReference get_address = new MethodReference("Address", t_ref, array);
                            for (int r = 0; r < array.Rank; r++)
                            {
                                get_address.Parameters.Add(new ParameterDefinition(TypeInt32));
                            }
                            get_address.HasThis = true;

                            // emit the get_address call
                            for (int r = 0; r < array.Rank; r++)
                            {
                                il.Emit(OpCodes.Ldc_I4, 0);
                            }
                            il.Emit(OpCodes.Call, get_address);
                        }

                        // end: fixed (IntPtr ptr = &array[0])
                        il.Append(end);
                        il.Emit(OpCodes.Ldloc, pinned_index);
                        il.Emit(OpCodes.Conv_I);
                    }
                    else
                    {
                        EmitStringArrayParameter(method, p, body, il);
                    }
                }
            }
            return i;
        }
开发者ID:RetroAchievements,项目名称:opentk,代码行数:101,代码来源:Program.cs

示例9: DefineServices

        /// <summary>
        /// Defines the instructions that create each service type in the <paramref name="serviceMap"/>.
        /// </summary>
        /// <param name="serviceMap">The service map that contains the list of application dependencies.</param>
        /// <param name="getInstanceMethod">The method that will be used to instantiate the service types.</param>
        /// <param name="jumpTargetField">The field that holds the dictionary with the switch table target instructions.</param>
        /// <param name="getServiceHash">The method that calculates the service hash code.</param>
        /// <param name="il">The <see cref="ILProcessor"/> that points to the body of the factory method.</param>
        private void DefineServices(IDictionary<IDependency, IImplementation> serviceMap, MethodDefinition getInstanceMethod, FieldDefinition jumpTargetField, MethodDefinition getServiceHash, ILProcessor il)
        {
            var endLabel = Instruction.Create(OpCodes.Nop);
            il.Append(endLabel);

            var body = il.Body;
            body.InitLocals = true;

            var method = body.Method;
            var returnValue = method.AddLocal<object>();
            var declaringType = method.DeclaringType;
            var module = declaringType.Module;

            var jumpTargets = new Dictionary<IDependency, Instruction>();
            foreach (var dependency in serviceMap.Keys)
            {
                jumpTargets[dependency] = il.Create(OpCodes.Nop);
            }

            var getItemMethod = module.ImportMethod<Dictionary<int, int>>("get_Item");
            var serviceHash = method.AddLocal<int>();
            var skipCreate = il.Create(OpCodes.Nop);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldarg_1);
            il.Emit(OpCodes.Ldarg_2);
            il.Emit(OpCodes.Call, getServiceHash);
            il.Emit(OpCodes.Stloc, serviceHash);

            var contains = module.ImportMethod<Dictionary<int, int>>("ContainsKey");
            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldloc, serviceHash);
            il.Emit(OpCodes.Callvirt, contains);
            il.Emit(OpCodes.Brfalse, skipCreate);

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Ldfld, jumpTargetField);
            il.Emit(OpCodes.Ldloc, serviceHash);
            il.Emit(OpCodes.Callvirt, getItemMethod);

            var switchLabels = new List<Instruction>(jumpTargets.Values);
            var labels = switchLabels.ToArray();
            il.Emit(OpCodes.Switch, labels);
            il.Emit(OpCodes.Ldnull);
            il.Emit(OpCodes.Stloc, returnValue);
            il.Emit(OpCodes.Br, skipCreate);

            foreach (var dependency in serviceMap.Keys)
            {
                // Set the jump target
                var currentLabel = jumpTargets[dependency];
                il.Append(currentLabel);

                var serviceType = module.ImportType(dependency.ServiceType);

                // Emit the implementation
                var implementation = serviceMap[dependency];
                EmitService(getInstanceMethod, dependency, implementation, serviceMap);

                il.Emit(OpCodes.Stloc, returnValue);

                var serviceInstance = returnValue;

                // Call IInitialize.Initialize(this) on the current type
                if (_initializer != null)
                    _initializer.Initialize(il, module, serviceInstance);

                //il.Emit(OpCodes.Ldloc, returnValue);
                //il.Emit(OpCodes.Unbox_Any, serviceType);

                il.Emit(OpCodes.Br, endLabel);
            }

            il.Append(skipCreate);

            var getNextContainer = module.ImportMethod<IMicroContainer>("get_NextContainer");
            var otherContainer = method.AddLocal<IMicroContainer>();

            il.Emit(OpCodes.Ldarg_0);
            il.Emit(OpCodes.Callvirt, getNextContainer);
            il.Emit(OpCodes.Stloc, otherContainer);

            // if (otherContainer != null ) {
            var skipOtherContainerCall = il.Create(OpCodes.Nop);
            il.Emit(OpCodes.Ldloc, otherContainer);
            il.Emit(OpCodes.Brfalse, skipOtherContainerCall);

            // Prevent the container from calling itself
            il.Emit(OpCodes.Ldloc, otherContainer);
            il.Emit(OpCodes.Ldarg_0);
//.........这里部分代码省略.........
开发者ID:philiplaureano,项目名称:Hiro,代码行数:101,代码来源:GetInstanceMethodImplementor.cs

示例10: WriteMessageId

 private static void WriteMessageId(ILProcessor worker, int msgId)
 {
     worker.Append(worker.Create(OpCodes.Ldloc_0));
     worker.Append(worker.Create(OpCodes.Ldc_I4, msgId));
     worker.Append(worker.Create(OpCodes.Conv_U2));
     worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
 }
开发者ID:CarlosHBC,项目名称:UnityDecompiled,代码行数:7,代码来源:NetworkBehaviourProcessor.cs

示例11: WriteDirtyCheck

 private static void WriteDirtyCheck(ILProcessor serWorker, bool reset)
 {
     Instruction target = serWorker.Create(OpCodes.Nop);
     serWorker.Append(serWorker.Create(OpCodes.Ldloc_0));
     serWorker.Append(serWorker.Create(OpCodes.Brtrue, target));
     serWorker.Append(serWorker.Create(OpCodes.Ldarg_1));
     serWorker.Append(serWorker.Create(OpCodes.Ldarg_0));
     serWorker.Append(serWorker.Create(OpCodes.Call, Weaver.NetworkBehaviourDirtyBitsReference));
     serWorker.Append(serWorker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWritePacked32));
     if (reset)
     {
         serWorker.Append(serWorker.Create(OpCodes.Ldc_I4_1));
         serWorker.Append(serWorker.Create(OpCodes.Stloc_0));
     }
     serWorker.Append(target);
 }
开发者ID:CarlosHBC,项目名称:UnityDecompiled,代码行数:16,代码来源:NetworkBehaviourProcessor.cs

示例12: GenerateSyncListInitializer

 private void GenerateSyncListInitializer(ILProcessor awakeWorker, FieldReference fd, int index)
 {
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldfld, fd));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldarg_0));
     awakeWorker.Append(awakeWorker.Create(OpCodes.Ldsfld, this.m_SyncListStaticFields[index]));
     GenericInstanceType baseType = (GenericInstanceType) fd.FieldType.Resolve().BaseType;
     baseType = (GenericInstanceType) Weaver.scriptDef.MainModule.ImportReference(baseType);
     TypeReference reference = baseType.GenericArguments[0];
     TypeReference[] arguments = new TypeReference[] { reference };
     MethodReference method = Helpers.MakeHostInstanceGeneric(Weaver.SyncListInitBehaviourReference, arguments);
     awakeWorker.Append(awakeWorker.Create(OpCodes.Callvirt, method));
     Weaver.scriptDef.MainModule.ImportReference(method);
 }
开发者ID:CarlosHBC,项目名称:UnityDecompiled,代码行数:14,代码来源:NetworkBehaviourProcessor.cs

示例13: EmitDebugPrologue

        static DebugVariables EmitDebugPrologue(MethodDefinition wrapper, ILProcessor il)
        {

            DebugVariables vars = null;
            if (il.Body.Method.Name != "GetError")
            {
                // Pull out the namespace name, method fullname will look 
                // something like "type namespace.class::method(type arg)"
                var module = il.Body.Method.FullName;
                module = module.Substring(module.IndexOf(' ') + 1);
                module = module.Substring(0, module.IndexOf("::"));
                module = module.Substring(0, module.LastIndexOf('.'));

                // Only works for Graphics modules due to hardcoded use of
                // OpenTK.Graphics.GraphicsContext
                if (module == "OpenTK.Graphics.OpenGL4" ||
                    module == "OpenTK.Graphics.OpenGL" ||
                    module == "OpenTK.Graphics.ES10" ||
                    module == "OpenTK.Graphics.ES11" ||
                    module == "OpenTK.Graphics.ES20" ||
                    module == "OpenTK.Graphics.ES30")
                {
                    var errorHelperType = wrapper.Module.GetType(module, "ErrorHelper");

                    if (errorHelperType != null)
                    {
                        vars = new DebugVariables();
                        vars.ErrorHelperType = errorHelperType;

                        // GraphicsContext type
                        var graphicsContext = wrapper.Module.Types.First(
                            type => type.FullName == "OpenTK.Graphics.GraphicsContext");

                        // IGraphicsContext type
                        var iGraphicsContext = wrapper.Module.Types.First(
                            type => type.FullName == "OpenTK.Graphics.IGraphicsContext");

                        // Get the constructor that takes a GraphicsContext parameter
                        var ctor = vars.ErrorHelperType.GetConstructors().FirstOrDefault(
                            c => c.Parameters.Count == 1 &&
                            c.Parameters[0].ParameterType.FullName == iGraphicsContext.FullName);

                        if (ctor == null)
                        {
                            throw new InvalidOperationException(
                                String.Format(
                                    "{0} does needs a constructor taking {1}",
                                    errorHelperType,
                                    graphicsContext));
                        }

                        // GraphicsContext.CurrentContext property getter
                        vars.Get_CurrentContext = graphicsContext.Methods.First(
                            method => method.Name == "get_CurrentContext");

                        vars.Set_ErrorChecking = graphicsContext.Methods.First(
                            method => method.Name == "set_ErrorChecking");

                        vars.ErrorHelperLocal = new VariableDefinition(vars.ErrorHelperType);

                        // using (new ErrorHelper(GraphicsContext.CurrentContext)) { ...
                        il.Body.Variables.Add(vars.ErrorHelperLocal);
                        il.Emit(OpCodes.Ldloca, vars.ErrorHelperLocal);
                        il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                        il.Emit(OpCodes.Call, ctor);

                        vars.BeginTry = Instruction.Create(OpCodes.Nop);
                        il.Append(vars.BeginTry);

                        // Special case Begin to turn off error checking.
                        if (il.Body.Method.Name == "Begin")
                        {
                            il.Emit(OpCodes.Call, vars.Get_CurrentContext);
                            il.Emit(OpCodes.Ldc_I4_0);
                            il.Emit(OpCodes.Conv_I1);
                            il.Emit(OpCodes.Call, vars.Set_ErrorChecking);
                        }
                    }
                }
            }

            return vars;
        }
开发者ID:RockyTV,项目名称:opentk,代码行数:83,代码来源:Program.cs

示例14: WriteMessageSize

 private static void WriteMessageSize(ILProcessor worker)
 {
     worker.Append(worker.Create(OpCodes.Ldc_I4_0));
     worker.Append(worker.Create(OpCodes.Callvirt, Weaver.NetworkWriterWriteInt16));
 }
开发者ID:CarlosHBC,项目名称:UnityDecompiled,代码行数:5,代码来源:NetworkBehaviourProcessor.cs

示例15: DefaultValueMappingCode

 private void DefaultValueMappingCode(ILProcessor ilProcessor)
 {
     ilProcessor.Append(Instruction.Create(OpCodes.Ldsfld, _imports.ObjectFieldRef));
     ilProcessor.Append(Instruction.Create(OpCodes.Callvirt, _imports.PropertyMapIsUriRef));
 }
开发者ID:rafalrosochacki,项目名称:RomanticWeb,代码行数:5,代码来源:DictionaryMappingMetaFactory.cs


注:本文中的Mono.Cecil.Cil.ILProcessor.Append方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。