• MSIL实用指南-返回结果


    一个方法体执行完指令后,必须要完成调用并返回,这是要使用Ret指令。
    Ret指令的详细解释是从当前方法返回,并将返回值(如果存在)从被调用方的计算堆栈推送到调用方的计算堆栈上。就是说如果计算堆栈上没有变量,则返回void类型;如果有,则返回这个栈的变量,并且这个方法的返回类型就是栈上变量的数据类型。

    下面例子是返回一个整数类型

    ilInstaceGenerator.Emit(OpCodes.Ldc_I4,int.MaxValue);
    ilInstaceGenerator.Emit(OpCodes.Ret);

    完整的程序如下:

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        class Demo10_Ret
        {
            static string binaryName = "Demo10_Ret.exe";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "RetTest";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder mainMethod;
            static MethodBuilder GetMaxValueMethod;
            static ConstructorBuilder constructorBuilder;
    
            static void Emit_GetMaxValue()
            {
                GetMaxValueMethod = typeBuilder.DefineMethod("GetMaxValue", MethodAttributes.Public | MethodAttributes.Static,
                   typeof(int), new Type[] { });
                ILGenerator ilInstaceGenerator = GetMaxValueMethod.GetILGenerator();
                ilInstaceGenerator.Emit(OpCodes.Ldc_I4,int.MaxValue);
                ilInstaceGenerator.Emit(OpCodes.Ret);
            }
    
            public static void Generate()
            {
                InitAssembly();
                typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public);
                constructorBuilder = typeBuilder.DefineDefaultConstructor( MethodAttributes.Public);
                Emit_GetMaxValue();
                EmitMain();
    
                /*  设置assembly入口方法 */
                assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
                SaveAssembly();
                Console.WriteLine("生成成功");
            }
    
            static void EmitMain()
            {
                mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public 
                    | MethodAttributes.Static, typeof(void), new Type[] { });
                ILGenerator mainILGenerator = mainMethod.GetILGenerator();
    
                mainILGenerator.Emit(OpCodes.Call, GetMaxValueMethod);
                mainILGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }));
    
                MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
                mainILGenerator.Emit(OpCodes.Call, readKeyMethod);
                mainILGenerator.Emit(OpCodes.Pop);
                mainILGenerator.Emit(OpCodes.Ret);
    
            }
    
            static void InitAssembly()
            {
                AssemblyName assemblyName = new AssemblyName(namespaceName);
                assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndSave);
                moduleBuilder = assemblyBuilder.DefineDynamicModule(assemblyName.Name, binaryName);
            }
    
            static void SaveAssembly()
            {
                Type t = typeBuilder.CreateType(); //完成Type,这是必须的
                assemblyBuilder.Save(binaryName);
            }
        }
    }
    View Code
  • 相关阅读:
    Unity打包ARCore项目失败,但是其他安卓项目成功
    关于Unity 图片队列存储以及出列导致内存溢出的解决方案
    unity 使用 outline 组件
    7Z解压工具的BUG
    Unity ILRuntime 调用方法一览
    Python 免费插件
    SQL经典面试题及答案
    PL/SQL Developer中文注释乱码的解决办法
    Tomcat并发优化和缓存优化
    在配置hibernate.cfg.xml时需指定使用数据库的方言:
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8629996.html
Copyright © 2020-2023  润新知