最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

詳解c# Emit技術(shù)

 更新時間:2020年12月21日 09:47:11   作者:Min.Xiaoshuang  
這篇文章主要介紹了c# Emit技術(shù)的相關(guān)資料,幫助大家更好的理解和使用c#,感興趣的朋友可以了解下

我們常常有一個應(yīng)用場景,由我們的C#代碼,動態(tài)生成一個EXE,其應(yīng)用場景可以非常多,比如軟件授權(quán),可以輸入授權(quán)信息后,生成一個授權(quán)的DLL等,那如何實現(xiàn)這個功能呢,就要提到一個技術(shù)Emit。

1、Emit概述

Emit,可以稱為發(fā)出或者產(chǎn)生。在Framework中,與Emit相關(guān)的類基本都存在于System.Reflection.Emit命名
空間下??梢奅mit是作為反射的一個元素存在的。說道反射,大家應(yīng)該都不陌生,它允許我們查看程序集的元素據(jù),從而取得形如程序集包含哪些類型,類型包
含哪些方法等等大量的信息。但是反射也僅能夠‘看',而Emit則可以在運行時動態(tài)生成代碼。接下來就來看看如何用Emit生成代碼。

2、程序集(Assembly)和模塊(Managed Module)

程序集是一個或多個模塊、資源文件的邏輯性分組,其次程序集是重用,安全性和版本控制的最小單元。我們所見到的DLL、EXE都可以稱為一個Assembly,一個Assembly里面包含多個Module,不過通常,我們VS編譯的時候,會只編譯一個Module,假如在一個Assembly中要編譯多個Module,則要借助csc.exe實現(xiàn)。

3、動態(tài)生成代碼操作

定義程序集

 //定義一個程序集的名稱
 var asmName = new AssemblyName("MyClass");

//首先就需要定義一個程序集
 var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

定義模塊,和指定程序集的保存名稱

//定義一個構(gòu)建類
var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");

定義一個類 和方法

//定義一個類
 var defClassBuilder =defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);
 //定義一個方法
var methodBldr = defClassBuilder.DefineMethod("MyMethod",
  MethodAttributes.Public,
   null,//返回類型
   null//參數(shù)的類型
 );

以上通過創(chuàng)建,已經(jīng)確定了程序集和模塊,也定義了當前模塊中的一個類和方法,但這個類的MyMethod方法只定義了一個聲明,并沒有定義實體操作,以下就需要應(yīng)用到Emit技術(shù)中一個技術(shù)OpCode。

OpCode 是描述中間語言 (IL) 指令。這個指令非常多,可以查看微軟官網(wǎng):https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.opcodes?view=netframework-4.8

通過OpCode我們可以定義方法的內(nèi)容如下:

//獲取IL生成器
      var il = defMethodBuilder.GetILGenerator();
      //定義一個字符串
      il.Emit(OpCodes.Ldstr, "生成的第一個程序");
      //調(diào)用一個函數(shù)
      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
      //返回到方法開始(返回)
      il.Emit(OpCodes.Ret);

通過以上的定義,我們完成了一個程序集、模塊、類和方法的定義,我們怎么把以上的定義的信息進行創(chuàng)建和保存,需要調(diào)用以下函數(shù):

    //創(chuàng)建類型
      defClassBuilder.CreateType();

      //保存程序集
      defAssembly.Save("MyAssemblydll");

我們可以在運行程序看到如下效果:

以下通過創(chuàng)建程序集,并且調(diào)用的代碼如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp1
{
  class Program
  {
    static void Main(string[] args)
    {

      CreateAssembly();
      LoadAssembly();

      Console.ReadKey();
    }

    public static void LoadAssembly()
    {
      var ass = AppDomain.CurrentDomain.Load("MyAssembly");
      var m = ass.GetModule("MyModule");
      var ts = m.GetTypes();
      var t = ts.FirstOrDefault();
      if (t != null)
      {
        object obj = Activator.CreateInstance(t);
        var me = t.GetMethod("MyMethod");
        me.Invoke(obj, null);
      }
    }
    public static void CreateAssembly()
    {


      //定義一個程序集的名稱
      var asmName = new AssemblyName("MyAssembly");

      //首先就需要定義一個程序集
      var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
      //定義一個構(gòu)建類
      var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");


      //定義一個類
      var defClassBuilder = defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);

      //定義一個方法
      var defMethodBuilder = defClassBuilder.DefineMethod("MyMethod",
        MethodAttributes.Public,
        null,//返回類型
        null//參數(shù)類型
        );
      //獲取IL生成器
      var il = defMethodBuilder.GetILGenerator();
      //定義一個字符串
      il.Emit(OpCodes.Ldstr, "生成的第一個程序");
      //調(diào)用一個函數(shù)
      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
      //返回到方法開始(返回)
      il.Emit(OpCodes.Ret);

      //創(chuàng)建類型
      defClassBuilder.CreateType();

      //保存程序集
      defAssembly.Save("MyAssembly.dll");
    }

  }
}

顯示效果如下:

以上就是詳解c# Emit技術(shù)的詳細內(nèi)容,更多關(guān)于c# Emit技術(shù)的資料請關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Entity?Framework配置關(guān)系

    Entity?Framework配置關(guān)系

    這篇文章介紹了Entity?Framework配置關(guān)系的方法,文中通過示例代碼介紹的非常詳細。對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2022-06-06
  • C#用委托BeginInvoke做異步線程

    C#用委托BeginInvoke做異步線程

    今天小編就為大家分享一篇關(guān)于C#用委托BeginInvoke做異步線程,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • C#實現(xiàn)文件上傳下載Excel文檔示例代碼

    C#實現(xiàn)文件上傳下載Excel文檔示例代碼

    這篇文章主要介紹了C#實現(xiàn)文件上傳下載Excel文檔示例代碼,需要的朋友可以參考下
    2017-08-08
  • C#代碼延時的幾種實現(xiàn)

    C#代碼延時的幾種實現(xiàn)

    本文主要介紹了C#代碼延時的幾種實現(xiàn),主要介紹了三種方法,文中通過示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • C#中GDI+繪制圓弧及圓角矩形等比縮放的繪制

    C#中GDI+繪制圓弧及圓角矩形等比縮放的繪制

    這篇文章主要介紹了C#中GDI+繪制圓弧及圓角矩形等比縮放的繪制,文章圍繞主題展開詳細的內(nèi)容戒殺,具有一定的參考價值,需要的小伙伴可以參考一下
    2022-08-08
  • C#從文件流讀取xml文件到DataSet并顯示的方法

    C#從文件流讀取xml文件到DataSet并顯示的方法

    這篇文章主要介紹了C#從文件流讀取xml文件到DataSet并顯示的方法,實例分析了C#操作XML文件的技巧與DataSet的使用方法,需要的朋友可以參考下
    2015-04-04
  • C#基于NPOI生成具有精確列寬行高的Excel文件的方法

    C#基于NPOI生成具有精確列寬行高的Excel文件的方法

    這篇文章主要介紹了C#基于NPOI生成具有精確列寬行高的Excel文件的方法,是C#項目開發(fā)中非常實用的技巧,需要的朋友可以參考下
    2014-09-09
  • C#使用DirectX.DirectSound播放語音

    C#使用DirectX.DirectSound播放語音

    這篇文章主要為大家詳細介紹了C#使用DirectX.DirectSound播放語音,文中示例代碼介紹的非常詳細,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • xml 中的冒號 讀取問題的解決

    xml 中的冒號 讀取問題的解決

    c#讀取xml時因為冒號問題的解決方法
    2008-03-03
  • C# winform實現(xiàn)登陸次數(shù)限制

    C# winform實現(xiàn)登陸次數(shù)限制

    這篇文章主要介紹了C# winform實現(xiàn)登陸次數(shù)限制,相信大家都遇到過網(wǎng)站在用戶多次輸錯密碼之后會自動把賬戶凍結(jié)的情況,這種功能如何實現(xiàn),下面小編為大家分享實現(xiàn)方法
    2016-05-05

最新評論

汶上县| 衡水市| 铜川市| 平舆县| 岱山县| 陆良县| 柘荣县| 福海县| 若羌县| 永仁县| 德惠市| 普安县| 开封县| 雷波县| 保定市| 西盟| 吉安市| 九寨沟县| 济源市| 泾阳县| 元氏县| 柞水县| 镶黄旗| 乌什县| 富锦市| 策勒县| 吴堡县| 万山特区| 玛曲县| 大埔县| 安吉县| 云浮市| 治多县| 阳曲县| 林周县| 锦州市| 高邮市| 惠东县| 岚皋县| 旺苍县| 敖汉旗|