• MSIL实用指南-一维数组的操作


    本篇讲解怎么生成和操作一维数组。各种数组类型创建的步骤是一样的,但是加载和保存步骤有所不同。


    一.创建数组
    所有类型的一维数组创建都是一样的,分三步。
    1.加载数组长度
    2.生成指令 Newarr <数组成员类型>
    3.保存

    实例代码:

    ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte)100);
    ilGenerator.Emit(OpCodes.Newarr, typeof(int));
    ilGenerator.Emit(OpCodes.Stloc_0);

    二.数组的成员保存
    这里的数组类型是byte、short、int、long、float、double和其它。它们的保存到成员的步骤是相似的。
    首先以int型为例,它有四步。
    1.加载数组变量
    2.加载索引号
    3.加载值
    4.生成Stelem_I4指令

    实例程序:

    ilGenerator.Emit(OpCodes.Ldloc_0);
    ilGenerator.Emit(OpCodes.Ldc_I4_0);
    ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
    ilGenerator.Emit(OpCodes.Stelem_I4);

    其它几种类型的前三步和int类型是一样的,只有最后一步不同,它们各有各的指令,对应关系是

    byte:Stelem_I1
    short:Stelem_I2
    int:Stelem_I4
    long:Stelem_I8
    float:Stelem_R4
    double:Stelem_R8
    其它:Stelem_Ref

    三.其它类型的成员加载
    加载也和保存类似。首先以int型数组为例,要分三步
    1.加载数组变量
    2.加载索引号
    3.生成Ldelem_I4指令
    实例程序:

    ilGenerator.Emit(OpCodes.Ldloc_0);
    ilGenerator.Emit(OpCodes.Ldc_I4_0); 
    ilGenerator.Emit(OpCodes.Ldelem_I4);
    

      

    其它类型的第三步指令各不相同,对应关系是
    byte:Ldelem_I1
    short:Ldelem_I2
    int:Ldelem_I4
    long:Ldelem_I8
    float:Ldelem_R4
    double:Ldelem_R8
    其它:Ldelem_Ref


    完整的程序如下

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        public class Demo21_ArrayOne
        {
            static string binaryName = "Demo21_ArrayOne.dll";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "DemoArrayOne";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder methodBuilder;
            static ILGenerator ilGenerator;
            public static void Generate()
            {
                InitAssembly();
                typeBuilder = moduleBuilder.DefineType(namespaceName + "." + typeName, TypeAttributes.Public | TypeAttributes.Abstract);
    
                methodBuilder = typeBuilder.DefineMethod("TestArray",
                     MethodAttributes.Public | MethodAttributes.Static,
                     typeof(void), new Type[] { });
                ilGenerator = methodBuilder.GetILGenerator();
    
                LocalBuilder localBuilderv1 = ilGenerator.DeclareLocal(typeof(int[]));
                LocalBuilder localBuilderv2 = ilGenerator.DeclareLocal(typeof(int));
                LocalBuilder localBuilderv3 = ilGenerator.DeclareLocal(typeof(float[]));
                LocalBuilder localBuilderv4 = ilGenerator.DeclareLocal(typeof(float));
                LocalBuilder localBuilderv5 = ilGenerator.DeclareLocal(typeof(string[]));
                LocalBuilder localBuilderv6 = ilGenerator.DeclareLocal(typeof(string));
    
                ilGenerator.Emit(OpCodes.Nop);
                Generate_IntArray();
                Generate_FloatArray();
                Generate_StringArray();
    
                ilGenerator.Emit(OpCodes.Ret);
                SaveAssembly();
                Console.WriteLine("生成成功");
            }
    
            static void Generate_IntArray()
            {
                ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte)100);
                ilGenerator.Emit(OpCodes.Newarr, typeof(int));
                ilGenerator.Emit(OpCodes.Stloc_0);
    
                ilGenerator.Emit(OpCodes.Ldloc_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Ldc_I4, int.MaxValue);
                ilGenerator.Emit(OpCodes.Stelem_I4);
    
                ilGenerator.Emit(OpCodes.Ldloc_0);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);   
                ilGenerator.Emit(OpCodes.Ldelem_I4);
                ilGenerator.Emit(OpCodes.Stloc_1);
            }
    
            static void Generate_FloatArray()
            {
                ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte)20);
                ilGenerator.Emit(OpCodes.Newarr, typeof(float));
                ilGenerator.Emit(OpCodes.Stloc_2);
    
                ilGenerator.Emit(OpCodes.Ldloc_2);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Ldc_I4, float.MaxValue);
                ilGenerator.Emit(OpCodes.Stelem_R4);
    
                ilGenerator.Emit(OpCodes.Ldloc_2);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Ldelem_R4);
                ilGenerator.Emit(OpCodes.Stloc_3);
            }
    
            static void Generate_StringArray()
            {
                ilGenerator.Emit(OpCodes.Ldc_I4_S, (sbyte)30);
                ilGenerator.Emit(OpCodes.Newarr, typeof(string));
                ilGenerator.Emit(OpCodes.Stloc_S, (sbyte)4);
    
                ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte)4);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Ldstr,"test string");
                ilGenerator.Emit(OpCodes.Stelem_Ref);
    
                ilGenerator.Emit(OpCodes.Ldloc_S, (sbyte)4);
                ilGenerator.Emit(OpCodes.Ldc_I4_0);
                ilGenerator.Emit(OpCodes.Ldelem_Ref);
                ilGenerator.Emit(OpCodes.Stloc_S, (sbyte)5);
            }
        
            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
  • 相关阅读:
    弹出新窗口
    网页布局之二 二列和三列
    JavaScript prototype
    window和linux开启动顺序
    ASP.net和javascript结合产生乱码的问题
    网页布局之一:XHTML CSS基础知识
    Study Android Chapter 1 Reading
    C++文件的读取
    心智模式
    各种排序算法的稳定性和时间复杂度小结
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8723036.html
Copyright © 2020-2023  润新知