zoukankan      html  css  js  c++  java
  • 反射之人千万不能错过的 EmitHelper

    微软最近貌似要在 SilverLight 和 DLR 上下狠功夫,动态语言的流行和广泛使用的趋势已经是必然,无聊的我浏览了一下DLR的源代码,一堆堆的 ILGenerator.Emit 语句映入眼帘,写过 .NET 语言编译器或者玩过 MSIL 的同学们肯定对这些东西颇为熟悉,如果你恨透了这一行行的 Emit(OpCodes....)...  那你一定要试试 BLToolkit 中的 EmitHelper 以及其他的一些 Reflection 相关的东西,下面的代码使用了 BLToolkit.Reflection.EmitHelper,啊..这才是给人读的代码啊.....

    Title

    using System;

    using System.Collections.Generic;

    using System.Text;

    using System.IO;

    using System.Reflection;

    using System.Reflection.Emit;

     

    using BLToolkit.Reflection;

    using BLToolkit.Reflection.Emit;

     

    namespace Adrian.Reflection

    {

        class Program

        {

            static void Main(string[] args)

            {

                string asName = "hw.exe";

                AssemblyBuilderHelper assem = new AssemblyBuilderHelper(asName);

                TypeBuilderHelper type = assem.DefineType("Emit.Program", TypeAttributes.Public, t.Object);

     

                MethodBuilderHelper add = type.DefineMethod("Add", MethodAttributes.Public | MethodAttributes.Static, t.Int32, new Type[] { t.Int32Array });

                add.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "nums");

                EmitHelper addIL = add.Emitter;

                addIL.DeclareLocal(t.Int32);

                addIL.DeclareLocal(t.Int32);

     

                Label cmp = addIL.DefineLabel();

                Label end = addIL.DefineLabel();

     

                addIL

                .ldc_i4_0

                .stloc_0

                .ldc_i4_0

                .stloc_1

                .MarkLabel(cmp)

                .ldloc_1

                .ldarg_0

                .ldlen

                .conv_i4

                .clt

                .brfalse_s(end)

                .ldloc_0

                .ldarg_0

                .ldloc_1

                .ldelem_i4

                .add

                .stloc_0

                .ldloc_1

                .ldc_i4_1

                .add

                .stloc_1

                .br_s(cmp)

                .MarkLabel(end)

                .ldloc_0

                .ret();

     

     

                MethodBuilderHelper main = type.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, t.Void, new Type[] { t.StringArray });

                main.MethodBuilder.DefineParameter(1, ParameterAttributes.None, "args");

                EmitHelper mainIL = main.Emitter;

                mainIL.DeclareLocal(t.Int32Array);

     

                mainIL

                .ldc_i4_3

                .newarr(t.Int32)

                .stloc_0

                .ldloc_0

                .ldc_i4_0

                .ldc_i4_1

                .stelem_i4

                .ldloc_0

                .ldc_i4_1

                .ldc_i4_2

                .stelem_i4

                .ldloc_0

                .ldc_i4_2

                .ldc_i4_3

                .stelem_i4

                .ldloc_0

                .call(add)

                .call(typeof(Console), "WriteLine", t.Int32)

                .ret();

     

                type.Create();

                assem.AssemblyBuilder.SetEntryPoint(main, PEFileKinds.ConsoleApplication);

                assem.Save();

     

                Assembly newAs = Assembly.LoadFile(Path.GetFullPath(asName));

                newAs.EntryPoint.Invoke(null, new object[] { new string[] { } });

            }

        }

     

        class t

        {

            private static Type _int32 = typeof(Int32);

            private static Type _int32Array = typeof(Int32[]);

            private static Type _object = typeof(Object);

            private static Type _void = typeof(void);

            private static Type _string = typeof(String);

            private static Type _stringArray = typeof(String[]);

     

            public static Type StringArray

            {

                get { return t._stringArray; }

            }

     

            public static Type String

            {

                get { return t._string; }

            }

     

            public static Type Void

            {

                get { return t._void; }

            }

     

            public static Type Object

            {

                get { return t._object; }

            }

     

            public static Type Int32Array

            {

                get { return t._int32Array; }

            }

     

            public static Type Int32

            {

                get { return _int32; }

            }

        }

    }


    中间的那两段 IL 是不是很像Visual C++里的内联汇编?其实 EmitHelper 只是对 ILGenerator 以及所有的 OpCode操作进行了封装,和直接使用 ILGenerator.Emit 是完全等价的, 写起来很有点 Intellisense 的感觉。
    废话不说了,BLToolkit 的主页是:http://www.bltoolkit.net/
    PS: BLToolkit 是开源的
  • 相关阅读:
    Linux_WEB访问控制示例(使用IPADDR类型)
    基于多IP地址Web服务
    基于多端口的Web服务
    基于多主机的Web服务
    Linux_WEB服务基础概念
    Linux_配置认证访问FTP服务
    Linux_配置匿名访问FTP服务
    Linux_部署日志服务器
    Linux_日志管理理论概述
    微信小程序 radio 单选框
  • 原文地址:https://www.cnblogs.com/Dah/p/738215.html
Copyright © 2011-2022 走看看