c\#Emit 기술 에 대한 자세 한 설명

5331 단어 c#Emit기술.
우 리 는 항상 하나의 응용 장면 이 있 습 니 다.우리 의 C\#코드 로 동태 적 으로 EXE 를 생 성 합 니 다.그 응용 장면 은 매우 많 습 니 다.예 를 들 어 소프트웨어 권한 수여,권한 수여 정 보 를 입력 한 후에 권한 을 수 여 받 은 DLL 을 생 성 할 수 있 습 니 다.그러면 이 기능 을 어떻게 실현 하 는 지 기술 Emit 를 언급 해 야 합 니 다.
1.Emit 개술
Emit,발송 또는 생 성 이 라 고 할 수 있 습 니 다.Framework 에서 Emit 와 관련 된 클래스 는 기본적으로 System.Reflection.Emit 이름 에 존재 합 니 다.
공간 아래.이 를 통 해 알 수 있 듯 이 Emit 는 반 사 된 요소 로 존재 합 니 다.반사 라 고 하면 모두 가 낯 설 지 않 을 것 입 니 다.프로그램 집합 에 포 함 된 요소 의 근 거 를 볼 수 있 도록 해 줍 니 다.예 를 들 어 프로그램 집합 이 어떤 유형,유형 패 키 지 를 포함 하 는 지 알 수 있 습 니 다.
어떤 방법 등 대량의 정 보 를 포함 합 니까?그러나 반사 도'보기'만 할 수 있 고,Emit 는 실행 중 동적 으로 코드 를 생 성 할 수 있다.다음은 Emit 로 코드 를 만 드 는 방법 을 살 펴 보 겠 습 니 다.
2.프로그램 집합(Assembly)과 모듈(Managed Module)
프로그램 집합 은 하나 이상 의 모듈,자원 파일 의 논리 적 그룹 이 고 그 다음 에 프로그램 집합 은 재 활용,안전성 과 버 전 제어 의 최소 단위 입 니 다.우리 가 본 DLL,EXE 는 하나의 Assembly 라 고 할 수 있 습 니 다.하나의 Assembly 에는 여러 개의 Module 이 포함 되 어 있 습 니 다.그러나 보통 우리 VS 컴 파일 할 때 하나의 Module 만 컴 파일 합 니 다.만약 에 하나의 Assembly 에서 여러 개의 Module 을 컴 파일 하려 면 csc.exe 를 통 해 이 루어 져 야 합 니 다.
3.동적 생 성 코드 조작
정의 프로그램 집합

 //          
 var asmName = new AssemblyName("MyClass");

//            
 var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);
모듈 과 지정 한 프로그램 집합 저장 이름 을 정의 합 니 다.

//       
var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");
클래스 와 방법 정의

//     
 var defClassBuilder =defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);
 //      
var methodBldr = defClassBuilder.DefineMethod("MyMethod",
  MethodAttributes.Public,
   null,//    
   null//     
 );
이상 은 생 성 을 통 해 프로그램 집합 과 모듈 을 확 정 했 고 현재 모듈 의 클래스 와 방법 도 정 의 했 습 니 다.그러나 이러한 MyMethod 방법 은 하나의 성명 만 정 의 했 을 뿐 실체 조작 을 정의 하지 않 았 습 니 다.다음은 Emit 기술 의 기술 OpCode 에 응용 해 야 합 니 다.
옵 코드 는 중간 언어(IL)명령 을 설명 하 는 것 이다.이 지령 은 매우 많아 서 마이크로소프트 홈 페이지 를 볼 수 있다.
OpCode 를 통 해 우 리 는 방법의 내용 을 다음 과 같이 정의 할 수 있다.

//  IL   
      var il = defMethodBuilder.GetILGenerator();
      //       
      il.Emit(OpCodes.Ldstr, "        ");
      //      
      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
      //       (  )
      il.Emit(OpCodes.Ret);
이상 의 정 의 를 통 해 우 리 는 프로그램 집합,모듈,클래스 와 방법의 정 의 를 완 성 했 습 니 다.우 리 는 상기 정 의 된 정 보 를 어떻게 만 들 고 저장 하 는 지 다음 과 같은 함 수 를 호출 해 야 합 니 다.

    //    
      defClassBuilder.CreateType();

      //     
      defAssembly.Save("MyAssemblydll");
우 리 는 실행 프로그램 에서 다음 과 같은 효 과 를 볼 수 있다.

다음은 프로그램 집합 을 만 들 고 호출 된 코드 는 다음 과 같 습 니 다.

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);
      //       
      var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");


      //     
      var defClassBuilder = defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);

      //      
      var defMethodBuilder = defClassBuilder.DefineMethod("MyMethod",
        MethodAttributes.Public,
        null,//    
        null//    
        );
      //  IL   
      var il = defMethodBuilder.GetILGenerator();
      //       
      il.Emit(OpCodes.Ldstr, "        ");
      //      
      il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
      //       (  )
      il.Emit(OpCodes.Ret);

      //    
      defClassBuilder.CreateType();

      //     
      defAssembly.Save("MyAssembly.dll");
    }

  }
}
다음 과 같은 효과 보이 기:

이상 은 c\#Emit 기술 에 대한 상세 한 내용 입 니 다.c\#Emit 기술 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기