ILGenerator.Emit 메서드
정의
중요
일부 정보는 릴리스되기 전에 상당 부분 수정될 수 있는 시험판 제품과 관련이 있습니다. Microsoft는 여기에 제공된 정보에 대해 어떠한 명시적이거나 묵시적인 보증도 하지 않습니다.
JIT(Just-In-Time) 컴파일러에 대한 MSIL(Microsoft Intermediate Language) 스트림에 명령을 넣습니다.
오버로드
| Name | Description |
|---|---|
| Emit(OpCode, LocalBuilder) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림과 지정된 지역 변수의 인덱스 뒤에 배치합니다. |
| Emit(OpCode, Type) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음 지정된 형식에 대한 메타데이터 토큰을 넣습니다. |
| Emit(OpCode, String) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음 지정된 문자열에 대한 메타데이터 토큰을 넣습니다. |
| Emit(OpCode, Single) |
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다. |
| Emit(OpCode, SByte) |
지정된 명령 및 문자 인수를 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다. |
| Emit(OpCode, FieldInfo) |
지정된 필드의 지정된 명령 및 메타데이터 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다. |
| Emit(OpCode, SignatureHelper) |
지정된 명령 및 서명 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다. |
| Emit(OpCode, Label[]) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치하고 수정이 완료되면 레이블을 포함할 공간을 둡니다. |
| Emit(OpCode, MethodInfo) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음, 지정된 메서드에 대한 메타데이터 토큰을 넣습니다. |
| Emit(OpCode, ConstructorInfo) |
지정된 생성자에 대해 지정된 명령 및 메타데이터 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다. |
| Emit(OpCode, Int64) |
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다. |
| Emit(OpCode, Int32) |
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다. |
| Emit(OpCode, Int16) |
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다. |
| Emit(OpCode, Double) |
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다. |
| Emit(OpCode, Byte) |
지정된 명령 및 문자 인수를 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다. |
| Emit(OpCode) |
지정된 명령을 명령 스트림에 넣습니다. |
| Emit(OpCode, Label) |
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치하고 수정이 완료되면 레이블을 포함할 공간을 둡니다. |
Emit(OpCode, LocalBuilder)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림과 지정된 지역 변수의 인덱스 뒤에 배치합니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::LocalBuilder ^ local);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.LocalBuilder local);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.LocalBuilder -> unit
Public MustOverride Sub Emit (opcode As OpCode, local As LocalBuilder)
Public Overridable Sub Emit (opcode As OpCode, local As LocalBuilder)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- local
- LocalBuilder
지역 변수입니다.
예외
매개 변수의 부모 메서드가 local 이 ILGenerator메서드와 연결된 메서드와 일치하지 않습니다.
local은 null입니다.
opcode 는 단일 바이트 명령이며 local 인덱스가 1보다 Byte.MaxValue큰 지역 변수를 나타냅니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Type)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음 지정된 형식에 대한 메타데이터 토큰을 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, Type ^ cls);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, Type cls);
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
abstract member Emit : System.Reflection.Emit.OpCode * Type -> unit
override this.Emit : System.Reflection.Emit.OpCode * Type -> unit
Public MustOverride Sub Emit (opcode As OpCode, cls As Type)
Public Overridable Sub Emit (opcode As OpCode, cls As Type)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
- cls
- Type
Type입니다.
예외
cls은 null입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다. 모듈을 cls PE(이식 가능한 실행 파일) 파일에 유지할 때 필요한 경우 토큰을 패치할 수 있도록 위치가 기록됩니다.
적용 대상
Emit(OpCode, String)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음 지정된 문자열에 대한 메타데이터 토큰을 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::String ^ str);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, string str);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, string str);
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
abstract member Emit : System.Reflection.Emit.OpCode * string -> unit
override this.Emit : System.Reflection.Emit.OpCode * string -> unit
Public MustOverride Sub Emit (opcode As OpCode, str As String)
Public Overridable Sub Emit (opcode As OpCode, str As String)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- str
- String
String 내보낸 것입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다. 모듈이 PE(이식 가능한 실행 파일) 파일에 유지되는 경우 향후 수정을 위해 위치 str 가 기록됩니다.
적용 대상
Emit(OpCode, Single)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, float arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, float arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, float arg);
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
abstract member Emit : System.Reflection.Emit.OpCode * single -> unit
override this.Emit : System.Reflection.Emit.OpCode * single -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Single)
Public Overridable Sub Emit (opcode As OpCode, arg As Single)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, SByte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
Important
이 API는 CLS 규격이 아닙니다.
지정된 명령 및 문자 인수를 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다.
public:
void Emit(System::Reflection::Emit::OpCode opcode, System::SByte arg);
[System.CLSCompliant(false)]
public void Emit(System.Reflection.Emit.OpCode opcode, sbyte arg);
[<System.CLSCompliant(false)>]
member this.Emit : System.Reflection.Emit.OpCode * sbyte -> unit
Public Sub Emit (opcode As OpCode, arg As SByte)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
- arg
- SByte
명령 직후 스트림에 푸시된 문자 인수입니다.
- 특성
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, FieldInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 필드의 지정된 명령 및 메타데이터 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::FieldInfo ^ field);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.FieldInfo field);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.FieldInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, field As FieldInfo)
Public Overridable Sub Emit (opcode As OpCode, field As FieldInfo)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- field
- FieldInfo
FieldInfo 필드를 나타내는 값입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다. 모듈을 field PE(이식 가능한 실행 파일) 파일에 유지할 때 필요한 경우 명령 스트림을 패치할 수 있도록 위치가 기록됩니다.
적용 대상
Emit(OpCode, SignatureHelper)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 서명 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::SignatureHelper ^ signature);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.SignatureHelper signature);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.SignatureHelper -> unit
Public MustOverride Sub Emit (opcode As OpCode, signature As SignatureHelper)
Public Overridable Sub Emit (opcode As OpCode, signature As SignatureHelper)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- signature
- SignatureHelper
서명 토큰을 생성하기 위한 도우미입니다.
예외
signature은 null입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Label[])
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치하고 수정이 완료되면 레이블을 포함할 공간을 둡니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, cli::array <System::Reflection::Emit::Label> ^ labels);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label[] labels);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label[] -> unit
Public MustOverride Sub Emit (opcode As OpCode, labels As Label())
Public Overridable Sub Emit (opcode As OpCode, labels As Label())
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- labels
- Label[]
이 위치에서 분기할 레이블 개체의 배열입니다. 모든 레이블이 사용됩니다.
예제
아래 코드 샘플에서는 점프 테이블을 사용하여 동적 메서드를 만드는 방법을 보여 줍니다. 점프 테이블은 의 배열을 사용하여 빌드됩니다 Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
설명
스위치 테이블을 내보낸다.
명령 값은 열거형에 OpCodes 정의됩니다.
레이블은 사용하여 DefineLabel 만들어지고 스트림 내의 위치는 .를 사용하여 MarkLabel수정됩니다. 싱글바이트 명령을 사용하는 경우 레이블은 스트림을 따라 최대 127바이트의 점프를 나타낼 수 있습니다.
opcode 는 분기 명령을 나타내야 합니다. 분기는 상대 지침 label 이므로 수정 프로세스 중에 올바른 오프셋에서 분기로 바뀝니다.
적용 대상
Emit(OpCode, MethodInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치한 다음, 지정된 메서드에 대한 메타데이터 토큰을 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::MethodInfo ^ meth);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.MethodInfo meth);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.MethodInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, meth As MethodInfo)
Public Overridable Sub Emit (opcode As OpCode, meth As MethodInfo)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- meth
- MethodInfo
MethodInfo 메서드를 나타내는 형식입니다.
예외
meth은 null입니다.
meth 는 속성이 있는 IsGenericMethodDefinition 제네릭 메서드입니다 false.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
모듈을 meth PE(이식 가능한 실행 파일) 파일에 유지할 때 필요한 경우 명령 스트림을 패치할 수 있도록 위치가 기록됩니다.
제네릭 메서드를 나타내는 경우 meth 제네릭 메서드 정의여야 합니다. 즉, MethodInfo.IsGenericMethodDefinition 속성은 이어야 true합니다.
적용 대상
Emit(OpCode, ConstructorInfo)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 생성자에 대해 지정된 명령 및 메타데이터 토큰을 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::ConstructorInfo ^ con);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
[System.Runtime.InteropServices.ComVisible(true)]
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.ConstructorInfo con);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
[<System.Runtime.InteropServices.ComVisible(true)>]
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.ConstructorInfo -> unit
Public MustOverride Sub Emit (opcode As OpCode, con As ConstructorInfo)
Public Overridable Sub Emit (opcode As OpCode, con As ConstructorInfo)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- con
- ConstructorInfo
ConstructorInfo 생성자를 나타내는 형식입니다.
- 특성
예외
con은 null입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
모듈을 con PE(이식 가능한 실행 파일) 파일에 유지할 때 필요한 경우 명령 스트림을 패치할 수 있도록 위치가 기록됩니다.
적용 대상
Emit(OpCode, Int64)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, long arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, long arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, long arg);
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int64 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int64 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Long)
Public Overridable Sub Emit (opcode As OpCode, arg As Long)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
- arg
- Int64
명령 직후 스트림에 푸시된 숫자 인수입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Int32)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, int arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, int arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, int arg);
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int -> unit
override this.Emit : System.Reflection.Emit.OpCode * int -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Integer)
Public Overridable Sub Emit (opcode As OpCode, arg As Integer)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
- arg
- Int32
명령 직후 스트림에 푸시된 숫자 인수입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Int16)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, short arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, short arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, short arg);
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
abstract member Emit : System.Reflection.Emit.OpCode * int16 -> unit
override this.Emit : System.Reflection.Emit.OpCode * int16 -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Short)
Public Overridable Sub Emit (opcode As OpCode, arg As Short)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- arg
- Int16
Int 명령 직후에 스트림에 푸시된 인수입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Double)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 숫자 인수를 명령의 msIL(Microsoft 중간 언어) 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, double arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, double arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, double arg);
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
abstract member Emit : System.Reflection.Emit.OpCode * double -> unit
override this.Emit : System.Reflection.Emit.OpCode * double -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Double)
Public Overridable Sub Emit (opcode As OpCode, arg As Double)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다. 열거형에 OpCodes 정의되어 있습니다.
- arg
- Double
명령 직후 스트림에 푸시된 숫자 인수입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode, Byte)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령 및 문자 인수를 MSIL(Microsoft 중간 언어) 명령 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Byte arg);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, byte arg);
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
abstract member Emit : System.Reflection.Emit.OpCode * byte -> unit
override this.Emit : System.Reflection.Emit.OpCode * byte -> unit
Public MustOverride Sub Emit (opcode As OpCode, arg As Byte)
Public Overridable Sub Emit (opcode As OpCode, arg As Byte)
매개 변수
- opcode
- OpCode
스트림에 넣을 MSIL 명령입니다.
- arg
- Byte
명령 직후 스트림에 푸시된 문자 인수입니다.
설명
명령 값은 열거형에 OpCodes 정의됩니다.
적용 대상
Emit(OpCode)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 명령 스트림에 넣습니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode);
public abstract void Emit(System.Reflection.Emit.OpCode opcode);
public virtual void Emit(System.Reflection.Emit.OpCode opcode);
abstract member Emit : System.Reflection.Emit.OpCode -> unit
abstract member Emit : System.Reflection.Emit.OpCode -> unit
override this.Emit : System.Reflection.Emit.OpCode -> unit
Public MustOverride Sub Emit (opcode As OpCode)
Public Overridable Sub Emit (opcode As OpCode)
매개 변수
- opcode
- OpCode
스트림에 배치할 MSIL(Microsoft Intermediate Language) 명령입니다.
예제
아래 코드 샘플에서는 인스턴스ILGenerator를 통해 MSIL 출력을 생성하는 데 사용하는 Emit 방법을 보여 줍니다.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
설명
매개 변수에 opcode 인수가 필요한 경우 호출자는 인수 길이가 선언된 매개 변수의 길이와 일치하는지 확인해야 합니다. 그렇지 않으면 결과를 예측할 수 없습니다. 예를 들어 내보내기 명령에 2바이트 피연산자가 필요하고 호출자가 4바이트 피연산자를 제공하는 경우 런타임은 명령 스트림에 2바이트를 추가로 내보낸다. 이러한 추가 바이트는 지침입니다 Nop .
명령 값은 .에 정의되어 있습니다 OpCodes.
적용 대상
Emit(OpCode, Label)
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
- Source:
- ILGenerator.cs
지정된 명령을 MSIL(Microsoft 중간 언어) 스트림에 배치하고 수정이 완료되면 레이블을 포함할 공간을 둡니다.
public:
abstract void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public:
virtual void Emit(System::Reflection::Emit::OpCode opcode, System::Reflection::Emit::Label label);
public abstract void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
public virtual void Emit(System.Reflection.Emit.OpCode opcode, System.Reflection.Emit.Label label);
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
abstract member Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
override this.Emit : System.Reflection.Emit.OpCode * System.Reflection.Emit.Label -> unit
Public MustOverride Sub Emit (opcode As OpCode, label As Label)
Public Overridable Sub Emit (opcode As OpCode, label As Label)
매개 변수
- opcode
- OpCode
스트림에 내보낸 MSIL 명령입니다.
- label
- Label
이 위치에서 분기할 레이블입니다.
예제
아래 코드 샘플에서는 점프 테이블을 사용하여 동적 메서드를 만드는 방법을 보여 줍니다. 점프 테이블은 의 배열을 사용하여 빌드됩니다 Label.
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class DynamicJumpTableDemo
{
public static Type BuildMyType()
{
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.Run);
ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(
"MyJumpTableDemo");
TypeBuilder myTypeBuilder = myModBuilder.DefineType("JumpTableDemo",
TypeAttributes.Public);
MethodBuilder myMthdBuilder = myTypeBuilder.DefineMethod("SwitchMe",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(string),
new Type[] {typeof(int)});
ILGenerator myIL = myMthdBuilder.GetILGenerator();
Label defaultCase = myIL.DefineLabel();
Label endOfMethod = myIL.DefineLabel();
// We are initializing our jump table. Note that the labels
// will be placed later using the MarkLabel method.
Label[] jumpTable = new Label[] { myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel(),
myIL.DefineLabel() };
// arg0, the number we passed, is pushed onto the stack.
// In this case, due to the design of the code sample,
// the value pushed onto the stack happens to match the
// index of the label (in IL terms, the index of the offset
// in the jump table). If this is not the case, such as
// when switching based on non-integer values, rules for the correspondence
// between the possible case values and each index of the offsets
// must be established outside of the ILGenerator.Emit calls,
// much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0);
myIL.Emit(OpCodes.Switch, jumpTable);
// Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase);
// Case arg0 = 0
myIL.MarkLabel(jumpTable[0]);
myIL.Emit(OpCodes.Ldstr, "are no bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 1
myIL.MarkLabel(jumpTable[1]);
myIL.Emit(OpCodes.Ldstr, "is one banana");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 2
myIL.MarkLabel(jumpTable[2]);
myIL.Emit(OpCodes.Ldstr, "are two bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 3
myIL.MarkLabel(jumpTable[3]);
myIL.Emit(OpCodes.Ldstr, "are three bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Case arg0 = 4
myIL.MarkLabel(jumpTable[4]);
myIL.Emit(OpCodes.Ldstr, "are four bananas");
myIL.Emit(OpCodes.Br_S, endOfMethod);
// Default case
myIL.MarkLabel(defaultCase);
myIL.Emit(OpCodes.Ldstr, "are many bananas");
myIL.MarkLabel(endOfMethod);
myIL.Emit(OpCodes.Ret);
return myTypeBuilder.CreateType();
}
public static void Main()
{
Type myType = BuildMyType();
Console.Write("Enter an integer between 0 and 5: ");
int theValue = Convert.ToInt32(Console.ReadLine());
Console.WriteLine("---");
Object myInstance = Activator.CreateInstance(myType, new object[0]);
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe",
BindingFlags.InvokeMethod,
null,
myInstance,
new object[] {theValue}));
}
}
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class DynamicJumpTableDemo
Public Shared Function BuildMyType() As Type
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.Run)
Dim myModBuilder As ModuleBuilder = myAsmBuilder.DefineDynamicModule("MyJumpTableDemo")
Dim myTypeBuilder As TypeBuilder = myModBuilder.DefineType("JumpTableDemo", _
TypeAttributes.Public)
Dim myMthdBuilder As MethodBuilder = myTypeBuilder.DefineMethod("SwitchMe", _
MethodAttributes.Public Or MethodAttributes.Static, _
GetType(String), New Type() {GetType(Integer)})
Dim myIL As ILGenerator = myMthdBuilder.GetILGenerator()
Dim defaultCase As Label = myIL.DefineLabel()
Dim endOfMethod As Label = myIL.DefineLabel()
' We are initializing our jump table. Note that the labels
' will be placed later using the MarkLabel method.
Dim jumpTable() As Label = {myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel(), _
myIL.DefineLabel()}
' arg0, the number we passed, is pushed onto the stack.
' In this case, due to the design of the code sample,
' the value pushed onto the stack happens to match the
' index of the label (in IL terms, the index of the offset
' in the jump table). If this is not the case, such as
' when switching based on non-integer values, rules for the correspondence
' between the possible case values and each index of the offsets
' must be established outside of the ILGenerator.Emit calls,
' much as a compiler would.
myIL.Emit(OpCodes.Ldarg_0)
myIL.Emit(OpCodes.Switch, jumpTable)
' Branch on default case
myIL.Emit(OpCodes.Br_S, defaultCase)
' Case arg0 = 0
myIL.MarkLabel(jumpTable(0))
myIL.Emit(OpCodes.Ldstr, "are no bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 1
myIL.MarkLabel(jumpTable(1))
myIL.Emit(OpCodes.Ldstr, "is one banana")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 2
myIL.MarkLabel(jumpTable(2))
myIL.Emit(OpCodes.Ldstr, "are two bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 3
myIL.MarkLabel(jumpTable(3))
myIL.Emit(OpCodes.Ldstr, "are three bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Case arg0 = 4
myIL.MarkLabel(jumpTable(4))
myIL.Emit(OpCodes.Ldstr, "are four bananas")
myIL.Emit(OpCodes.Br_S, endOfMethod)
' Default case
myIL.MarkLabel(defaultCase)
myIL.Emit(OpCodes.Ldstr, "are many bananas")
myIL.MarkLabel(endOfMethod)
myIL.Emit(OpCodes.Ret)
Return myTypeBuilder.CreateType()
End Function 'BuildMyType
Public Shared Sub Main()
Dim myType As Type = BuildMyType()
Console.Write("Enter an integer between 0 and 5: ")
Dim theValue As Integer = Convert.ToInt32(Console.ReadLine())
Console.WriteLine("---")
Dim myInstance As [Object] = Activator.CreateInstance(myType, New Object() {})
Console.WriteLine("Yes, there {0} today!", myType.InvokeMember("SwitchMe", _
BindingFlags.InvokeMethod, Nothing, _
myInstance, New Object() {theValue}))
End Sub
End Class
설명
명령 값은 열거형에 OpCodes 정의됩니다.
레이블은 를 사용하여 DefineLabel만들어지고 스트림 내의 위치는 .를 사용하여 MarkLabel수정됩니다. 싱글바이트 명령을 사용하는 경우 레이블은 스트림을 따라 최대 127바이트의 점프를 나타낼 수 있습니다.
opcode 는 분기 명령을 나타내야 합니다. 분기는 상대 지침 label 이므로 수정 프로세스 중에 올바른 오프셋에서 분기로 바뀝니다.