首页 > 代码库 > ILGenerator.Emit动态 MSIL编程(二)

ILGenerator.Emit动态 MSIL编程(二)

    public sealed class ColorToArgb
    {
        /// <summary>
        /// 将十六进制转化为AGRB
        /// </summary>
        /// <param name="Hexadecimal"></param>
        /// <returns></returns>
        public static Color HexadecimalToArgb(string Hexadecimal)
        {

            string text = string.Empty;
            int num = 1;
            byte b = 255;
            int num2;
            switch (Hexadecimal.Length)
            {
                case 4:
                    num2 = 1;
                    text = "F";
                    goto IL_9D;
                case 5:
                    num2 = 1;
                    text = "F";
                    b = Convert.ToByte(Hexadecimal.Substring(num, num2) + text, 16);
                    num += num2;
                    goto IL_9D;
                case 7:
                    num2 = 2;
                    goto IL_9D;
                case 9:
                    num2 = 2;
                    b = Convert.ToByte(Hexadecimal.Substring(num, num2) + text, 16);
                    num += num2;
                    goto IL_9D;
            }
            num2 = 2;
            Hexadecimal = "#FFFFFF";
        IL_9D:
            byte b2 = Convert.ToByte(Hexadecimal.Substring(num, num2) + text, 16);
            byte b3 = Convert.ToByte(Hexadecimal.Substring(num += num2, num2) + text, 16);
            byte b4 = Convert.ToByte(Hexadecimal.Substring(num + num2, num2) + text, 16);
            return Color.FromArgb(b, b2, b3, b4);
        }
    }
      
class Program
    {
        static void Main(string[] args)
        {
            #region
            var asmName = new AssemblyName("Test");
            var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);//创建程序集
            var mdlBldr = asmBuilder.DefineDynamicModule("Test", "Test.dll");//定义模块
            var typeBldr = mdlBldr.DefineType("ColorToArgb", TypeAttributes.Public|TypeAttributes.Class|TypeAttributes.Sealed);//定义类
            var methodBldr = typeBldr.DefineMethod("HexadecimalToArgb", MethodAttributes.Public,CallingConventions.Standard, 
                typeof(Color), new Type[] { typeof(string) });//定义方法
            var MyILGenerator = methodBldr.GetILGenerator();//获取il生成器
            MyILGenerator.DeclareLocal(typeof(string));//注册变量 string text
            MyILGenerator.DeclareLocal(typeof(int));//int num ;
            MyILGenerator.DeclareLocal(typeof(byte));//byte b;
            MyILGenerator.DeclareLocal(typeof(int));//int num2;
            var b2 = MyILGenerator.DeclareLocal(typeof(byte));
            var b3 = MyILGenerator.DeclareLocal(typeof(byte));
            var b4 = MyILGenerator.DeclareLocal(typeof(byte));
            var color = MyILGenerator.DeclareLocal(typeof(Color));
            
            #endregion
            #region
            //Label defaultCase = MyILGenerator.DefineLabel();
            Label endOfMethod = MyILGenerator.DefineLabel();
            Label forLabel = MyILGenerator.DefineLabel();
            Label[] jumpTable = new Label[] { MyILGenerator.DefineLabel(),MyILGenerator.DefineLabel(),
                      MyILGenerator.DefineLabel(), MyILGenerator.DefineLabel() };
            MyILGenerator.Emit(OpCodes.Ldsfld, string.Empty); //压栈赋值
            MyILGenerator.Emit(OpCodes.Stloc_0);
            MyILGenerator.Emit(OpCodes.Ldc_I4, 1);
            MyILGenerator.Emit(OpCodes.Stloc_1);
            MyILGenerator.Emit(OpCodes.Ldc_I4, 0XFF);
            MyILGenerator.Emit(OpCodes.Stloc_2);
            MyILGenerator.Emit(OpCodes.Ldarg, 0);//Ldarg是加载方法参数的意思。这里arg_0事实上是对当前对象的引用即this
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetProperty("Length").GetGetMethod());
            LocalBuilder length = MyILGenerator.DeclareLocal(typeof(int));
            MyILGenerator.Emit(OpCodes.Stloc_S, length);
            MyILGenerator.Emit(OpCodes.Ldloc_S, length); 
            MyILGenerator.Emit(OpCodes.Ldc_I4_4);
            MyILGenerator.Emit(OpCodes.Sub);
            MyILGenerator.Emit(OpCodes.Switch,jumpTable);
            //MyILGenerator.Emit(OpCodes.Br_S, defaultCase);
            MyILGenerator.MarkLabel(jumpTable[0]);
            MyILGenerator.Emit(OpCodes.Ldc_I4_1);
            MyILGenerator.Emit(OpCodes.Stloc_3);
            
            MyILGenerator.Emit(OpCodes.Ldstr, "F");
            MyILGenerator.Emit(OpCodes.Stloc_0);
            MyILGenerator.Emit(OpCodes.Ldarg_0);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Substring", new Type[] { typeof(Int32), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Ldloc_0);
            MyILGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            MyILGenerator.Emit(OpCodes.Ldc_I4_S, 16);
            MyILGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToByte", new Type[] { typeof(string), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_2);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Add);
            MyILGenerator.Emit(OpCodes.Stloc_1);
            //MyILGenerator.Emit(OpCodes.Br_S, endOfMethod);
            MyILGenerator.MarkLabel(jumpTable[1]);
            MyILGenerator.Emit(OpCodes.Ldc_I4_2);
            MyILGenerator.Emit(OpCodes.Stloc_3);
            //MyILGenerator.Emit(OpCodes.Br_S, endOfMethod);
            MyILGenerator.MarkLabel(jumpTable[2]);
            MyILGenerator.Emit(OpCodes.Ldc_I4_2);
            MyILGenerator.Emit(OpCodes.Stloc_3);
            MyILGenerator.Emit(OpCodes.Ldarg_0);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Substring", new Type[] { typeof(Int32), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Ldloc_0);
            MyILGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            MyILGenerator.Emit(OpCodes.Ldc_I4_S, 16);
            MyILGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToByte", new Type[] { typeof(string), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_2);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Add);
            MyILGenerator.Emit(OpCodes.Stloc_1);
            //MyILGenerator.Emit(OpCodes.Br_S, endOfMethod);
            MyILGenerator.MarkLabel(jumpTable[3]);
            MyILGenerator.Emit(OpCodes.Ldc_I4_2);
            MyILGenerator.Emit(OpCodes.Stloc_3);
            MyILGenerator.Emit(OpCodes.Ldstr, "#FFFFFF");
            MyILGenerator.Emit(OpCodes.Starg_S);//, "Hexadecimal");
            MyILGenerator.Emit(OpCodes.Ldarg_0);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Substring", new Type[] { typeof(Int32), typeof(Int32) }));

            MyILGenerator.Emit(OpCodes.Ldloc_0);
            MyILGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            MyILGenerator.Emit(OpCodes.Ldc_I4_S, 16);
            MyILGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToByte", new Type[] { typeof(string), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_S, b2);
            MyILGenerator.Emit(OpCodes.Ldarg_0);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Add);
            MyILGenerator.Emit(OpCodes.Dup);
            MyILGenerator.Emit(OpCodes.Stloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Substring", new Type[] { typeof(Int32), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Ldloc_0);
            MyILGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            MyILGenerator.Emit(OpCodes.Ldc_I4_S, 16);
            MyILGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToByte", new Type[] { typeof(string), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_S, b3);
            MyILGenerator.Emit(OpCodes.Ldarg_0);
            MyILGenerator.Emit(OpCodes.Ldloc_1);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Add);
            MyILGenerator.Emit(OpCodes.Ldloc_3);
            MyILGenerator.Emit(OpCodes.Callvirt, typeof(string).GetMethod("Substring", new Type[] { typeof(Int32), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Ldloc_0);
            MyILGenerator.Emit(OpCodes.Call, typeof(string).GetMethod("Concat", new Type[] { typeof(string), typeof(string) }));
            MyILGenerator.Emit(OpCodes.Ldc_I4_S, 16);
            MyILGenerator.Emit(OpCodes.Call, typeof(Convert).GetMethod("ToByte", new Type[] { typeof(string), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_S, b4);
            MyILGenerator.Emit(OpCodes.Ldloc_2);
            MyILGenerator.Emit(OpCodes.Stloc_S, b2);
            MyILGenerator.Emit(OpCodes.Stloc_S, b3);
            MyILGenerator.Emit(OpCodes.Stloc_S, b4);
            MyILGenerator.Emit(OpCodes.Call, typeof(Color).GetMethod("FromArgb", new Type[] { typeof(Int32), typeof(Int32), typeof(Int32), typeof(Int32) }));
            MyILGenerator.Emit(OpCodes.Stloc_S, color);
            MyILGenerator.Emit(OpCodes.Br_S, forLabel);
            MyILGenerator.MarkLabel(forLabel);
            MyILGenerator.Emit(OpCodes.Ldloc_S, color);
            MyILGenerator.Emit(OpCodes.Ret);
            typeBldr.CreateType();
            asmBuilder.Save("Test.dll");//方便反编译 看代码写的对不对
            #endregion
        }
    }