|
|
2021-3-21 12:38:34에 게시됨
|
|
|
|

응용 시나리오는 C# 코드에 의해 동적으로 EXE를 생성하며, 소프트웨어 권한 부여, 권한 정보 입력, 권한 부여 DLL 생성 등 매우 다양할 수 있습니다. 이 기능을 구현하려면 기술적 Emit을 언급해야 합니다.
1. 에밋 개요
방출(emmit)은 방출(emitting) 또는 생성(generateting)이라고 할 수 있습니다. 프레임워크에서 Emit과 관련된 클래스는 기본적으로 System.Reflection.Emit 네임스페이스 아래에 존재합니다. 에밋은 반사의 원소로 존재한다는 것을 알 수 있습니다. 반사에 대해 말하자면, 모두가 익숙해야 합니다. 이는 어셈블리의 요소를 볼 수 있게 해주어 어셈블리에 어떤 타입이 포함되는지, 타입이 어떤 메서드를 포함하는지 등 많은 정보를 얻을 수 있습니다. 하지만 반사는 오직 '볼 수 있는' 것만 가능하며, Emit은 런타임에 동적으로 코드를 생성할 수 있습니다. Emit으로 코드를 생성하는 방법을 살펴보겠습니다.
2. 조립 및 관리 모듈
어셈블리는 하나 이상의 모듈, 리소스 파일로 구성된 논리적 그룹이며, 부차적으로 어셈블리는 재사용, 보안, 버전 관리의 가장 작은 단위입니다. 우리가 보는 DLL과 EXE는 어셈블리라고 부를 수 있는데, 어셈블리는 여러 모듈을 포함하지만, 보통 VS 컴파일할 때는 하나의 모듈만 컴파일합니다. 어셈블리에서 여러 모듈을 컴파일하려면 csc.exe 구현을 사용해야 합니다.
3. 동적으로 코드 연산 생성
먼저, .NET에서 각 동적 타입이 어떤 타입으로 표현되는지 이해해야 합니다.
어셈블리: System.Reflection.Emit.AssemblyBuilder (동적 어셈블리를 정의하고 표현함)
구성자: System.Reflection.Emit.ConstructorBuilder (동적 클래스를 정의하고 표현하는 생성자)
커스텀 속성: System.Reflection.Emit.CustomAttributeBuilder (구성자가 전달한 매개변수를 사용해 클래스 속성을 생성하는 데 도움을 줍니다)
Enum: System.Reflection.Emit.EnumBuilder (enum 유형을 설명하고 표시함)
이벤트: System.Reflection.Emit.EventBuilder (클래스를 정의하는 이벤트)
필드: System.Reflection.Emit.FieldBuilder (필드를 정의하고 표현함.) 이 클래스를 상속할 수 없습니다)
로컬 변수: System.Reflection.Emit.LocalBuilder (메서드 또는 구성자 내의 로컬 변수 표현)
메서드: System.Reflection.Emit.MethodBuilder (동적 클래스를 정의하고 표현하는 메서드(또는 생성자)
모듈: System.Reflection.Emit.ModuleBuilder (동적 어셈블리에서 모듈을 정의하고 표현함)
Parameter: System.Reflection.Emit.ParameterBuilder (메서드 매개변수, 이벤트 매개변수 등과 같은 매개변수 정보를 생성하거나 연관)
속성: System.Reflection.Emit.PropertyBuilder (속성 유형 정의)
클래스: System.Reflection.Emit.TypeBuilder (런타임에 클래스의 새 인스턴스를 정의하고 생성합니다)
OpCode는 중간 언어(IL) 지시에 대한 설명입니다. 이 작업에 대한 많은 안내가 있으니 공식 마이크로소프트 웹사이트를 확인해 보세요:하이퍼링크 로그인이 보입니다.
AssemblyBuilder접근 제한
AssemblyBuilderAccess.Run; 어셈블리는 실행할 수 있지만 저장할 수는 없음을 나타냅니다. 어셈블리빌더액세스.저장; 조립은 저장할 수 있지만 실행은 불가능함을 나타냅니다. 어셈블리빌더액세스.런앤세이브; 어셈블리를 저장하고 실행할 수 있음을 나타냅니다. 어셈블리빌더접근.반영만; 어셈블리는 반성적 맥락에서만 사용할 수 있으며 실행될 수 없음을 나타냅니다. 어셈블리빌더액세스.런앤콜렉트; 어셈블리를 언로드하고 메모리를 회수할 수 있음을 나타냅니다.
코드는 다음과 같습니다:
먼저 emit을 사용해 IL 코드를 생성하고, 그 다음 동적으로 어셈블리를 생성한 뒤, 어셈블리를 로드하고 메서드를 호출합니다. 아래 그림에서 볼 수 있습니다:
아래 이미지에서 보이는 것처럼 ILSpy를 사용해 생성된 코드를 확인하세요:
(끝)
|
이전의:Roslyn MSBuild 컴파일러의 차이점다음:.NET/C# 반사, 방출, 표현 성능 테스트
|