• MSIL实用指南-加载null、string、long、float、double等值


    本篇讲述怎么加载null、string值、long值、float值、double值。

    加载null不需要参数值,只要

    Emit ldnull

    其它几个命令要

    Emit <指令> <值>

    加载null

    加载null是很简单的,使用OpCodes.Ldnull,以下一句程序就可以了。

    ilGenerator.Emit(OpCodes.Ldnull);

    加载string

    加载string值也很简单,使用OpCodes.Ldstr,格式是

    ilGenerator.Emit(OpCodes.Ldstr, <string值>);

    比如

    ilGenerator.Emit(OpCodes.Ldstr, "hello...");

    加载long

    使用格式OpCodes.Ldc_I8指令,是ilGenerator.Emit(OpCodes.Ldc_I8, <long值>);

    比如

    ilGenerator.Emit(OpCodes.Ldc_I8, long.MaxValue);

    需要注意的是,下面这一句是有问题的,120默认是int型,不是long型,生成的指令是没法正确运行的。

    ilGenerator.Emit(OpCodes.Ldc_I8, 120);

    必须加long强制转换,修正为

    ilGenerator.Emit(OpCodes.Ldc_I8, (long)120);

    加载float

    使用格式OpCodes.Ldc_R4指令,格式是ilGenerator.Emit(OpCodes.Ldc_R4, <float值>);

    比如

    ilGenerator.Emit(OpCodes.Ldc_R4, float.MinValue)

    也要注意的,下面这一句有问题,5.5默认是dobule型,不是float型,生成的指令也不能正确运行的。

    ilGenerator.Emit(OpCodes.Ldc_R4, 5.5);

    必须加long强制转换,修正为

    ilGenerator.Emit(OpCodes.Ldc_R4, (float)5.5);

    加载double

    使用格式OpCodes.Ldc_R8指令,格式是ilGenerator.Emit(OpCodes.Ldc_R4, <double值>);

    比如

    ilGenerator.Emit(OpCodes.Ldc_R8, (double)6.5);

    完整的程序如下:

    using System;
    using System.Reflection;
    using System.Reflection.Emit;
    
    namespace LX1_ILDemo
    {
        /// <summary>
        /// load null、string值、long值、float值、double值、
        /// </summary>
        class Demo02_LoadLFDSN
        {
            static string binaryName = "Demo02_LoadLFDSN.exe";
            static string namespaceName = "LX1_ILDemo";
            static string typeName = "LoadLFDSN";
    
            static AssemblyBuilder assemblyBuilder;
            static ModuleBuilder moduleBuilder;
            static TypeBuilder typeBuilder;
            static MethodBuilder mainMethod;
            static ILGenerator ilGenerator;
    
            static void Emit_Ldc()
            {
                /* 加载string值的Ldstr指令使用 */
                MethodInfo writeStringLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) });
    
                /* 加载null的Ldnull指令使用 */
                ilGenerator.Emit(OpCodes.Ldnull);//ldnull
                ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);
    
                /* 加载string的Ldstr指令使用 */
                ilGenerator.Emit(OpCodes.Ldstr, "hello...");//ldstr "hello..."
                ilGenerator.Emit(OpCodes.Call, writeStringLineMethod);
    
                /* 加载long值的Ldc_I8指令使用 */
                MethodInfo writeLongLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(long) });
                ilGenerator.Emit(OpCodes.Ldc_I8, (long)120);//数值前面的强制转换‘(long)’是必须的,默认会把‘120’作为int,导致生成的程序运行错误
                ilGenerator.Emit(OpCodes.Call, writeLongLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_I8, long.MaxValue);//ldc.i8     0x7fffffffffffffff
                ilGenerator.Emit(OpCodes.Call, writeLongLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_I8, long.MinValue);//ldc.i8     0x8000000000000000
                ilGenerator.Emit(OpCodes.Call, writeLongLineMethod);
    
                /* 加载float值的Ldc_R4指令使用 */
                MethodInfo writeFloatLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(float) });
                ilGenerator.Emit(OpCodes.Ldc_R4, (float)5.5);//数值前面的强制转换‘(float)’是必须的,默认会把‘5.5’作为double,导致生成的程序运行错误
                ilGenerator.Emit(OpCodes.Call, writeFloatLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_R4, float.MaxValue);//ldc.r4     3.4028235e+038
                ilGenerator.Emit(OpCodes.Call, writeFloatLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_R4, float.MinValue);//ldc.r4     -3.4028235e+038
                ilGenerator.Emit(OpCodes.Call, writeFloatLineMethod);
    
                /* 加载double值的Ldc_R8指令使用 */
                MethodInfo writeDoubleLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(double) });
                ilGenerator.Emit(OpCodes.Ldc_R8, (double)6.5);//ldc.r8     6.5
                ilGenerator.Emit(OpCodes.Call, writeDoubleLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_R8, double.MaxValue);//ldc.r8     1.7976931348623157e+308
                ilGenerator.Emit(OpCodes.Call, writeDoubleLineMethod);
                ilGenerator.Emit(OpCodes.Ldc_R8, double.MinValue);//ldc.r8     -1.7976931348623157e+308
                ilGenerator.Emit(OpCodes.Call, writeDoubleLineMethod);
            }
    
            public static void Generate()
            {
                InitAssembly();
    
                /* 生成 public class LoadLFDSN */
                typeBuilder = moduleBuilder.DefineType( namespaceName+"."+ typeName, TypeAttributes.Public);
    
                /* 生成 public static void Main() */
                GenerateMain();
    
                Emit_Ldc();
    
                EmitReadKey();
                ilGenerator.Emit(OpCodes.Ret);
    
                /*  设置assembly入口方法 */
                assemblyBuilder.SetEntryPoint(mainMethod, PEFileKinds.ConsoleApplication);
    
                SaveAssembly();
                Console.WriteLine("生成成功");
                //Console.ReadKey();
            }
    
            static void EmitReadKey()
            {
                /* 生成 Console.ReadKey(); */
                MethodInfo readKeyMethod = typeof(Console).GetMethod("ReadKey", new Type[] { });
                ilGenerator.Emit(OpCodes.Call, readKeyMethod);
                ilGenerator.Emit(OpCodes.Pop);
            }
    
            static void GenerateMain()
            {
                mainMethod = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(void), new Type[] { });
                ilGenerator = mainMethod.GetILGenerator();
            }
    
            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
  • 相关阅读:
    websocket的理解&应用&场景
    如何设置winform程序图标
    Python简单爬虫爬取自己博客园所有文章
    分享一个自己做的SpringMVC的PPT
    2016校招薪资汇总
    2016阿里巴巴校招offer面经
    利用快排partition求前N小的元素
    几个面试经典算法题Java解答
    深入理解java垃圾回收机制
    深入理解JVM结构
  • 原文地址:https://www.cnblogs.com/tkt2016/p/8573502.html
Copyright © 2020-2023  润新知