OpCodes クラス
ILGenerator クラス メンバ (Emit など) による出力に対する MSIL (Microsoft Intermediate Language) 命令のフィールド表現を提供します。
この型のすべてのメンバの一覧については、OpCodes メンバ を参照してください。
System.Object
System.Reflection.Emit.OpCodes
Public Class OpCodes
[C#]
public class OpCodes
[C++]
public __gc class OpCodes
[JScript]
public class OpCodes
スレッドセーフ
Reflection Emit は、Boolean パラメータ isSynchronized を true に設定して呼び出した AppDomain.DefineDynamicAssembly メソッドで作成されたアセンブリを使用する場合は、スレッド セーフです。
解説
メンバ オペコードの詳細については、「Tool Developers Guide」の「Common Language Infrastructure Instruction Set」のドキュメントを参照してください。
使用例
[Visual Basic, C#, C++] ILGenerator を使用して、動的メソッドを作成し、 OpCodes を MethodBuilder に出力する方法を次の例に示します。
Imports System
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
Class EmitWriteLineDemo
Public Shared Function CreateDynamicType() As Type
Dim ctorParams() As Type = {GetType(Integer), GetType(Integer)}
Dim myDomain As AppDomain = Thread.GetDomain()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBuilder As AssemblyBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave)
Dim pointModule As ModuleBuilder = myAsmBuilder.DefineDynamicModule("PointModule", "Point.dll")
Dim pointTypeBld As TypeBuilder = pointModule.DefineType("Point", _
TypeAttributes.Public)
Dim xField As FieldBuilder = pointTypeBld.DefineField("x", _
GetType(Integer), _
FieldAttributes.Public)
Dim yField As FieldBuilder = pointTypeBld.DefineField("y", _
GetType(Integer), _
FieldAttributes.Public)
Dim objType As Type = Type.GetType("System.Object")
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type(){})
Dim pointCtor As ConstructorBuilder = pointTypeBld.DefineConstructor( _
MethodAttributes.Public, _
CallingConventions.Standard, _
ctorParams)
Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
' First, you build the constructor.
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Call, objCtor)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_1)
ctorIL.Emit(OpCodes.Stfld, xField)
ctorIL.Emit(OpCodes.Ldarg_0)
ctorIL.Emit(OpCodes.Ldarg_2)
ctorIL.Emit(OpCodes.Stfld, yField)
ctorIL.Emit(OpCodes.Ret)
' Now, you'll build a method to output some information on the
' inside your dynamic class. This method will have the following
' definition in C#:
' Public Sub WritePoint()
Dim writeStrMthd As MethodBuilder = pointTypeBld.DefineMethod("WritePoint", _
MethodAttributes.Public, _
Nothing, Nothing)
Dim writeStrIL As ILGenerator = writeStrMthd.GetILGenerator()
' The below ILGenerator created demonstrates a few ways to create
' string output through STDIN.
' ILGenerator.EmitWriteLine(string) will generate a ldstr and a
' call to WriteLine for you.
writeStrIL.EmitWriteLine("The value of this current instance is:")
' Here, you will do the hard work yourself. First, you need to create
' the string we will be passing and obtain the correct WriteLine overload
' for said string. In the below case, you are substituting in two values,
' so the chosen overload is Console.WriteLine(string, object, object).
Dim inStr As [String] = "({0}, {1})"
Dim wlParams() As Type = {GetType(String), GetType(Object), GetType(Object)}
' We need the MethodInfo to pass into EmitCall later.
Dim writeLineMI As MethodInfo = GetType(Console).GetMethod("WriteLine", wlParams)
' Push the string with the substitutions onto the stack.
' This is the first argument for WriteLine - the string one.
writeStrIL.Emit(OpCodes.Ldstr, inStr)
' Since the second argument is an object, and it corresponds to
' to the substitution for the value of our integer field, you
' need to box that field to an object. First, push a reference
' to the current instance, and then push the value stored in
' field 'x'. We need the reference to the current instance (stored
' in local argument index 0) so Ldfld can load from the correct
' instance (this one).
writeStrIL.Emit(OpCodes.Ldarg_0)
writeStrIL.Emit(OpCodes.Ldfld, xField)
' Now, we execute the box opcode, which pops the value of field 'x',
' returning a reference to the integer value boxed as an object.
writeStrIL.Emit(OpCodes.Box, GetType(Integer))
' Atop the stack, you'll find our string inStr, followed by a reference
' to the boxed value of 'x'. Now, you need to likewise box field 'y'.
writeStrIL.Emit(OpCodes.Ldarg_0)
writeStrIL.Emit(OpCodes.Ldfld, yField)
writeStrIL.Emit(OpCodes.Box, GetType(Integer))
' Now, you have all of the arguments for your call to
' Console.WriteLine(string, object, object) atop the stack:
' the string InStr, a reference to the boxed value of 'x', and
' a reference to the boxed value of 'y'.
' Call Console.WriteLine(string, object, object) with EmitCall.
writeStrIL.EmitCall(OpCodes.Call, writeLineMI, Nothing)
' Lastly, EmitWriteLine can also output the value of a field
' using the overload EmitWriteLine(FieldInfo).
writeStrIL.EmitWriteLine("The value of 'x' is:")
writeStrIL.EmitWriteLine(xField)
writeStrIL.EmitWriteLine("The value of 'y' is:")
writeStrIL.EmitWriteLine(yField)
' Since we return no value (void), the the ret opcode will not
' return the top stack value.
writeStrIL.Emit(OpCodes.Ret)
Return pointTypeBld.CreateType()
End Function 'CreateDynamicType
Public Shared Sub Main()
Dim ctorParams(1) As Object
Console.Write("Enter a integer value for X: ")
Dim myX As String = Console.ReadLine()
Console.Write("Enter a integer value for Y: ")
Dim myY As String = Console.ReadLine()
Console.WriteLine("---")
ctorParams(0) = Convert.ToInt32(myX)
ctorParams(1) = Convert.ToInt32(myY)
Dim ptType As Type = CreateDynamicType()
Dim ptInstance As Object = Activator.CreateInstance(ptType, ctorParams)
ptType.InvokeMember("WritePoint", _
BindingFlags.InvokeMethod, _
Nothing, ptInstance, Nothing)
End Sub 'Main
End Class 'EmitWriteLineDemo
[C#]
using System;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
class EmitWriteLineDemo {
public static Type CreateDynamicType() {
Type[] ctorParams = new Type[] {typeof(int),
typeof(int)};
AppDomain myDomain = Thread.GetDomain();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.RunAndSave);
ModuleBuilder pointModule = myAsmBuilder.DefineDynamicModule("PointModule",
"Point.dll");
TypeBuilder pointTypeBld = pointModule.DefineType("Point",
TypeAttributes.Public);
FieldBuilder xField = pointTypeBld.DefineField("x", typeof(int),
FieldAttributes.Public);
FieldBuilder yField = pointTypeBld.DefineField("y", typeof(int),
FieldAttributes.Public);
Type objType = Type.GetType("System.Object");
ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);
ConstructorBuilder pointCtor = pointTypeBld.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
ctorParams);
ILGenerator ctorIL = pointCtor.GetILGenerator();
// First, you build the constructor.
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Call, objCtor);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_1);
ctorIL.Emit(OpCodes.Stfld, xField);
ctorIL.Emit(OpCodes.Ldarg_0);
ctorIL.Emit(OpCodes.Ldarg_2);
ctorIL.Emit(OpCodes.Stfld, yField);
ctorIL.Emit(OpCodes.Ret);
// Now, you'll build a method to output some information on the
// inside your dynamic class. This method will have the following
// definition in C#:
// public void WritePoint()
MethodBuilder writeStrMthd = pointTypeBld.DefineMethod(
"WritePoint",
MethodAttributes.Public,
typeof(void),
null);
ILGenerator writeStrIL = writeStrMthd.GetILGenerator();
// The below ILGenerator created demonstrates a few ways to create
// string output through STDIN.
// ILGenerator.EmitWriteLine(string) will generate a ldstr and a
// call to WriteLine for you.
writeStrIL.EmitWriteLine("The value of this current instance is:");
// Here, you will do the hard work yourself. First, you need to create
// the string we will be passing and obtain the correct WriteLine overload
// for said string. In the below case, you are substituting in two values,
// so the chosen overload is Console.WriteLine(string, object, object).
String inStr = "({0}, {1})";
Type[] wlParams = new Type[] {typeof(string),
typeof(object),
typeof(object)};
// We need the MethodInfo to pass into EmitCall later.
MethodInfo writeLineMI = typeof(Console).GetMethod(
"WriteLine",
wlParams);
// Push the string with the substitutions onto the stack.
// This is the first argument for WriteLine - the string one.
writeStrIL.Emit(OpCodes.Ldstr, inStr);
// Since the second argument is an object, and it corresponds to
// to the substitution for the value of our integer field, you
// need to box that field to an object. First, push a reference
// to the current instance, and then push the value stored in
// field 'x'. We need the reference to the current instance (stored
// in local argument index 0) so Ldfld can load from the correct
// instance (this one).
writeStrIL.Emit(OpCodes.Ldarg_0);
writeStrIL.Emit(OpCodes.Ldfld, xField);
// Now, we execute the box opcode, which pops the value of field 'x',
// returning a reference to the integer value boxed as an object.
writeStrIL.Emit(OpCodes.Box, typeof(int));
// Atop the stack, you'll find our string inStr, followed by a reference
// to the boxed value of 'x'. Now, you need to likewise box field 'y'.
writeStrIL.Emit(OpCodes.Ldarg_0);
writeStrIL.Emit(OpCodes.Ldfld, yField);
writeStrIL.Emit(OpCodes.Box, typeof(int));
// Now, you have all of the arguments for your call to
// Console.WriteLine(string, object, object) atop the stack:
// the string InStr, a reference to the boxed value of 'x', and
// a reference to the boxed value of 'y'.
// Call Console.WriteLine(string, object, object) with EmitCall.
writeStrIL.EmitCall(OpCodes.Call, writeLineMI, null);
// Lastly, EmitWriteLine can also output the value of a field
// using the overload EmitWriteLine(FieldInfo).
writeStrIL.EmitWriteLine("The value of 'x' is:");
writeStrIL.EmitWriteLine(xField);
writeStrIL.EmitWriteLine("The value of 'y' is:");
writeStrIL.EmitWriteLine(yField);
// Since we return no value (void), the the ret opcode will not
// return the top stack value.
writeStrIL.Emit(OpCodes.Ret);
return pointTypeBld.CreateType();
}
public static void Main() {
object[] ctorParams = new object[2];
Console.Write("Enter a integer value for X: ");
string myX = Console.ReadLine();
Console.Write("Enter a integer value for Y: ");
string myY = Console.ReadLine();
Console.WriteLine("---");
ctorParams[0] = Convert.ToInt32(myX);
ctorParams[1] = Convert.ToInt32(myY);
Type ptType = CreateDynamicType();
object ptInstance = Activator.CreateInstance(ptType, ctorParams);
ptType.InvokeMember("WritePoint",
BindingFlags.InvokeMethod,
null,
ptInstance,
new object[0]);
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
Type* CreateDynamicType() {
Type* ctorParams[] = {__typeof(int),
__typeof(int)};
AppDomain* myDomain = Thread::GetDomain();
AssemblyName* myAsmName = new AssemblyName();
myAsmName->Name = S"MyDynamicAssembly";
AssemblyBuilder* myAsmBuilder = myDomain->DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess::RunAndSave);
ModuleBuilder* pointModule = myAsmBuilder->DefineDynamicModule(S"PointModule",
S"Point.dll");
TypeBuilder* pointTypeBld = pointModule->DefineType(S"Point",
TypeAttributes::Public);
FieldBuilder* xField = pointTypeBld->DefineField(S"x", __typeof(int),
FieldAttributes::Public);
FieldBuilder* yField = pointTypeBld->DefineField(S"y", __typeof(int),
FieldAttributes::Public);
Type* objType = Type::GetType(S"System.Object");
ConstructorInfo* objCtor = objType->GetConstructor(new Type*[0]);
ConstructorBuilder* pointCtor = pointTypeBld->DefineConstructor(MethodAttributes::Public,
CallingConventions::Standard,
ctorParams);
ILGenerator* ctorIL = pointCtor->GetILGenerator();
// First, you build the constructor.
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Call, objCtor);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_1);
ctorIL->Emit(OpCodes::Stfld, xField);
ctorIL->Emit(OpCodes::Ldarg_0);
ctorIL->Emit(OpCodes::Ldarg_2);
ctorIL->Emit(OpCodes::Stfld, yField);
ctorIL->Emit(OpCodes::Ret);
// Now, you'll build a method to output some information on the
// inside your dynamic class. This method will have the following
// definition in C#:
// public void WritePoint()
MethodBuilder* writeStrMthd = pointTypeBld->DefineMethod(S"WritePoint",
MethodAttributes::Public,
__typeof(void),
0);
ILGenerator* writeStrIL = writeStrMthd->GetILGenerator();
// The below ILGenerator created demonstrates a few ways to create
// String* output through STDIN.
// ILGenerator::EmitWriteLine(String*) will generate a ldstr and a
// call to WriteLine for you.
writeStrIL->EmitWriteLine(S"The value of this current instance is:");
// Here, you will do the hard work yourself. First, you need to create
// the String* we will be passing and obtain the correct WriteLine overload
// for said String*. In the below case, you are substituting in two values,
// so the chosen overload is Console::WriteLine(String*, Object*, Object*).
String* inStr = S"( {0}, {1})";
Type* wlParams[] = {__typeof(String),
__typeof(Object),
__typeof(Object)};
// We need the MethodInfo to pass into EmitCall later.
MethodInfo* writeLineMI = __typeof(Console)->GetMethod(S"WriteLine",
wlParams);
// Push the String* with the substitutions onto the stack.
// This is the first argument for WriteLine - the String* one.
writeStrIL->Emit(OpCodes::Ldstr, inStr);
// Since the second argument is an Object*, and it corresponds to
// to the substitution for the value of our integer field, you
// need to box that field to an Object*. First, push a reference
// to the current instance, and then push the value stored in
// field 'x'. We need the reference to the current instance (stored
// in local argument index 0) so Ldfld can load from the correct
// instance (this one).
writeStrIL->Emit(OpCodes::Ldarg_0);
writeStrIL->Emit(OpCodes::Ldfld, xField);
// Now, we execute the box opcode, which pops the value of field 'x',
// returning a reference to the integer value boxed as an Object*.
writeStrIL->Emit(OpCodes::Box, __typeof(int));
// Atop the stack, you'll find our String* inStr, followed by a reference
// to the boxed value of 'x'. Now, you need to likewise box field 'y'.
writeStrIL->Emit(OpCodes::Ldarg_0);
writeStrIL->Emit(OpCodes::Ldfld, yField);
writeStrIL->Emit(OpCodes::Box, __typeof(int));
// Now, you have all of the arguments for your call to
// Console::WriteLine(String*, Object*, Object*) atop the stack:
// the String* InStr, a reference to the boxed value of 'x', and
// a reference to the boxed value of 'y'.
// Call Console::WriteLine(String*, Object*, Object*) with EmitCall.
writeStrIL->EmitCall(OpCodes::Call, writeLineMI, 0);
// Lastly, EmitWriteLine can also output the value of a field
// using the overload EmitWriteLine(FieldInfo).
writeStrIL->EmitWriteLine(S"The value of 'x' is:");
writeStrIL->EmitWriteLine(xField);
writeStrIL->EmitWriteLine(S"The value of 'y' is:");
writeStrIL->EmitWriteLine(yField);
// Since we return no value (void), the the ret opcode will not
// return the top stack value.
writeStrIL->Emit(OpCodes::Ret);
return pointTypeBld->CreateType();
}
int main() {
Object* ctorParams[] = new Object*[2];
Console::Write(S"Enter a integer value for X: ");
String* myX = Console::ReadLine();
Console::Write(S"Enter a integer value for Y: ");
String* myY = Console::ReadLine();
Console::WriteLine(S"---");
ctorParams[0] = __box(Convert::ToInt32(myX));
ctorParams[1] = __box(Convert::ToInt32(myY));
Type* ptType = CreateDynamicType();
Object* ptInstance = Activator::CreateInstance(ptType, ctorParams);
ptType->InvokeMember(S"WritePoint",
BindingFlags::InvokeMethod,
0,
ptInstance,
new Object*[0]);
}
[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン をクリックします。
必要条件
名前空間: System.Reflection.Emit
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ
アセンブリ: Mscorlib (Mscorlib.dll 内)