AssemblyBuilder.Save メソッド
この動的アセンブリをディスクに保存します。
Public Sub Save( _
ByVal assemblyFileName As String _)
[C#]
public void Save(stringassemblyFileName);
[C++]
public: void Save(String* assemblyFileName);
[JScript]
public function Save(
assemblyFileName : String);
パラメータ
- assemblyFileName
アセンブリのファイル名。
例外
例外の種類 | 条件 |
---|---|
ArgumentException | assemblyFileName の長さが 0 です。
または アセンブリに同じ名前で複数のモジュール リソース ファイルがあります。 または アセンブリの保存先ディレクトリが無効です。 または assemblyFileName が単純ファイル名ではありません (ディレクトリ コンポーネントまたはドライブ コンポーネントがあるなど)。または、バージョン情報リソースも含めて複数のアンマネージ リソースがこのアセンブリで定義されています。 または AssemblyCultureAttribute の CultureInfo 文字列が無効な文字列で、このメソッドを呼び出す前に DefineVersionInfoResource が呼び出されました。 |
ArgumentNullException | assemblyFileName が null 参照 (Visual Basic では Nothing) です。 |
InvalidOperationException | このアセンブリは既に保存されています。
または このアセンブリのアクセス モードが Run AssemblyBuilderAccess です。 |
IOException | 保存中に出力エラーが発生した場合。 |
NotSupportedException | ディスクに書き込むアセンブリのモジュール内のいずれかの型に対して CreateType が呼び出されていない場合。 |
SecurityException | 呼び出し元に、必要なアクセス許可がありません。 |
解説
このメソッドは、この動的アセンブリで定義されているすべての非遷移動的モジュールを保存します。遷移動的モジュールは保存されません。アセンブリ ファイル名は、いずれかのモジュール名と同じでもかまいません。この場合、アセンブリ情報はそのモジュールに格納されます。 assemblyFileName は、アセンブリに格納されているどのモジュール名とも異なっていてもかまいません。この場合、アセンブリはスタンドアロンとして格納されます。
DefineResource を使用して取得した ResourceWriter ごとに、このメソッドは .resources ファイルを書き込み、 Close を呼び出してストリームを閉じます。
assemblyFileName は、ドライブ コンポーネントまたはディレクトリ コンポーネントを含まない単純ファイル名にする必要があります。特定のディレクトリにアセンブリを作成するには、作成先ディレクトリ引数をとる DefineDynamicAssembly メソッドのいずれかを使用します。
使用例
[Visual Basic, C#, C++] 次のコード例は、動的なアセンブリを作成し、 Save を使用してローカル ディスクに永続化する方法を示しています。
Imports System
Imports System.Text
Imports System.Threading
Imports System.Reflection
Imports System.Reflection.Emit
_
' The Point class is the class we will reflect on and copy into our
' dynamic assembly. The public static function PointMain() will be used
' as our entry point.
'
' We are constructing the type seen here dynamically, and will write it
' out into a .exe file for later execution from the command-line.
' ---
' Class Point
'
' Private x As Integer
' Private y As Integer
'
'
' Public Sub New(ix As Integer, iy As Integer)
'
' Me.x = ix
' Me.y = iy
' End Sub 'New
'
'
' Public Function DotProduct(p As Point) As Integer
'
' Return Me.x * p.x + Me.y * p.y
' End Function 'DotProduct
'
'
' Public Shared Sub Main()
'
' Console.Write("Enter the 'x' value for point 1: ")
' Dim x1 As Integer = Convert.ToInt32(Console.ReadLine())
'
' Console.Write("Enter the 'y' value for point 1: ")
' Dim y1 As Integer = Convert.ToInt32(Console.ReadLine())
'
' Console.Write("Enter the 'x' value for point 2: ")
' Dim x2 As Integer = Convert.ToInt32(Console.ReadLine())
'
' Console.Write("Enter the 'y' value for point 2: ")
' Dim y2 As Integer = Convert.ToInt32(Console.ReadLine())
'
' Dim p1 As New Point(x1, y1)
' Dim p2 As New Point(x2, y2)
'
' Console.WriteLine("({0}, {1}) . ({2}, {3}) = {4}.", x1, y1, x2, y2, p1.DotProduct(p2))
' End Sub 'Main
' End Class 'Point
' ---
Class AssemblyBuilderDemo
Public Shared Function BuildDynAssembly() As Type
Dim pointType As Type = Nothing
Dim currentDom As AppDomain = Thread.GetDomain()
Console.Write("Please enter a name for your new assembly: ")
Dim asmFileNameBldr As New StringBuilder()
asmFileNameBldr.Append(Console.ReadLine())
asmFileNameBldr.Append(".exe")
Dim asmFileName As String = asmFileNameBldr.ToString()
Dim myAsmName As New AssemblyName()
myAsmName.Name = "MyDynamicAssembly"
Dim myAsmBldr As AssemblyBuilder = currentDom.DefineDynamicAssembly(myAsmName, _
AssemblyBuilderAccess.RunAndSave)
' We've created a dynamic assembly space - now, we need to create a module
' within it to reflect the type Point into.
Dim myModuleBldr As ModuleBuilder = myAsmBldr.DefineDynamicModule(asmFileName, _
asmFileName)
Dim myTypeBldr As TypeBuilder = myModuleBldr.DefineType("Point")
Dim xField As FieldBuilder = myTypeBldr.DefineField("x", GetType(Integer), _
FieldAttributes.Private)
Dim yField As FieldBuilder = myTypeBldr.DefineField("y", GetType(Integer), _
FieldAttributes.Private)
' Build the constructor.
Dim objType As Type = Type.GetType("System.Object")
Dim objCtor As ConstructorInfo = objType.GetConstructor(New Type() {})
Dim ctorParams() As Type = {GetType(Integer), GetType(Integer)}
Dim pointCtor As ConstructorBuilder = myTypeBldr.DefineConstructor( _
MethodAttributes.Public, _
CallingConventions.Standard, _
ctorParams)
Dim ctorIL As ILGenerator = pointCtor.GetILGenerator()
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)
' Build the DotProduct method.
Console.WriteLine("Constructor built.")
Dim pointDPBldr As MethodBuilder = myTypeBldr.DefineMethod("DotProduct", _
MethodAttributes.Public, _
GetType(Integer), _
New Type(0) {myTypeBldr})
Dim dpIL As ILGenerator = pointDPBldr.GetILGenerator()
dpIL.Emit(OpCodes.Ldarg_0)
dpIL.Emit(OpCodes.Ldfld, xField)
dpIL.Emit(OpCodes.Ldarg_1)
dpIL.Emit(OpCodes.Ldfld, xField)
dpIL.Emit(OpCodes.Mul_Ovf_Un)
dpIL.Emit(OpCodes.Ldarg_0)
dpIL.Emit(OpCodes.Ldfld, yField)
dpIL.Emit(OpCodes.Ldarg_1)
dpIL.Emit(OpCodes.Ldfld, yField)
dpIL.Emit(OpCodes.Mul_Ovf_Un)
dpIL.Emit(OpCodes.Add_Ovf_Un)
dpIL.Emit(OpCodes.Ret)
' Build the PointMain method.
Console.WriteLine("DotProduct built.")
Dim pointMainBldr As MethodBuilder = myTypeBldr.DefineMethod("PointMain", _
MethodAttributes.Public Or _
MethodAttributes.Static, _
Nothing, Nothing)
pointMainBldr.InitLocals = True
Dim pmIL As ILGenerator = pointMainBldr.GetILGenerator()
' We have four methods that we wish to call, and must represent as
' MethodInfo tokens:
' - Sub Console.WriteLine(string)
' - Function Console.ReadLine() As String
' - Function Convert.Int32(string) As Int
' - Sub Console.WriteLine(string, object[])
Dim writeMI As MethodInfo = GetType(Console).GetMethod("Write", _
New Type(0) {GetType(String)})
Dim readLineMI As MethodInfo = GetType(Console).GetMethod("ReadLine", _
New Type() {})
Dim convertInt32MI As MethodInfo = GetType(Convert).GetMethod("ToInt32", _
New Type(0) {GetType(String)})
Dim wlParams() As Type = {GetType(String), GetType(Object())}
Dim writeLineMI As MethodInfo = GetType(Console).GetMethod("WriteLine", wlParams)
' Although we could just refer to the local variables by
' index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
' this time, we'll use LocalBuilders for clarity and to
' demonstrate their usage and syntax.
Dim x1LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
Dim y1LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
Dim x2LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
Dim y2LB As LocalBuilder = pmIL.DeclareLocal(GetType(Integer))
Dim point1LB As LocalBuilder = pmIL.DeclareLocal(myTypeBldr)
Dim point2LB As LocalBuilder = pmIL.DeclareLocal(myTypeBldr)
Dim tempObjArrLB As LocalBuilder = pmIL.DeclareLocal(GetType(Object()))
pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 1: ")
pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
pmIL.Emit(OpCodes.Stloc, x1LB)
pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 1: ")
pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
pmIL.Emit(OpCodes.Stloc, y1LB)
pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 2: ")
pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
pmIL.Emit(OpCodes.Stloc, x2LB)
pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 2: ")
pmIL.EmitCall(OpCodes.Call, writeMI, Nothing)
pmIL.EmitCall(OpCodes.Call, readLineMI, Nothing)
pmIL.EmitCall(OpCodes.Call, convertInt32MI, Nothing)
pmIL.Emit(OpCodes.Stloc, y2LB)
pmIL.Emit(OpCodes.Ldloc, x1LB)
pmIL.Emit(OpCodes.Ldloc, y1LB)
pmIL.Emit(OpCodes.Newobj, pointCtor)
pmIL.Emit(OpCodes.Stloc, point1LB)
pmIL.Emit(OpCodes.Ldloc, x2LB)
pmIL.Emit(OpCodes.Ldloc, y2LB)
pmIL.Emit(OpCodes.Newobj, pointCtor)
pmIL.Emit(OpCodes.Stloc, point2LB)
pmIL.Emit(OpCodes.Ldstr, "({0}, {1}) . ({2}, {3}) = {4}.")
pmIL.Emit(OpCodes.Ldc_I4_5)
pmIL.Emit(OpCodes.Newarr, GetType([Object]))
pmIL.Emit(OpCodes.Stloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldc_I4_0)
pmIL.Emit(OpCodes.Ldloc, x1LB)
pmIL.Emit(OpCodes.Box, GetType(Integer))
pmIL.Emit(OpCodes.Stelem_Ref)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldc_I4_1)
pmIL.Emit(OpCodes.Ldloc, y1LB)
pmIL.Emit(OpCodes.Box, GetType(Integer))
pmIL.Emit(OpCodes.Stelem_Ref)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldc_I4_2)
pmIL.Emit(OpCodes.Ldloc, x2LB)
pmIL.Emit(OpCodes.Box, GetType(Integer))
pmIL.Emit(OpCodes.Stelem_Ref)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldc_I4_3)
pmIL.Emit(OpCodes.Ldloc, y2LB)
pmIL.Emit(OpCodes.Box, GetType(Integer))
pmIL.Emit(OpCodes.Stelem_Ref)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.Emit(OpCodes.Ldc_I4_4)
pmIL.Emit(OpCodes.Ldloc, point1LB)
pmIL.Emit(OpCodes.Ldloc, point2LB)
pmIL.EmitCall(OpCodes.Callvirt, pointDPBldr, Nothing)
pmIL.Emit(OpCodes.Box, GetType(Integer))
pmIL.Emit(OpCodes.Stelem_Ref)
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB)
pmIL.EmitCall(OpCodes.Call, writeLineMI, Nothing)
pmIL.Emit(OpCodes.Ret)
Console.WriteLine("PointMain (entry point) built.")
pointType = myTypeBldr.CreateType()
Console.WriteLine("Type completed.")
myAsmBldr.SetEntryPoint(pointMainBldr)
myAsmBldr.Save(asmFileName)
Console.WriteLine("Assembly saved as '{0}'.", asmFileName)
Console.WriteLine("Type '{0}' at the prompt to run your new " + "dynamically generated dot product calculator.", asmFileName)
' After execution, this program will have generated and written to disk,
' in the directory you executed it from, a program named
' <name_you_entered_here>.exe. You can run it by typing
' the name you gave it during execution, in the same directory where
' you executed this program.
Return pointType
End Function 'BuildDynAssembly
Public Shared Sub Main()
Dim myType As Type = BuildDynAssembly()
Console.WriteLine("---")
' Let's invoke the type 'Point' created in our dynamic assembly.
Dim ptInstance As Object = Activator.CreateInstance(myType, New Object(1) {0, 0})
myType.InvokeMember("PointMain", BindingFlags.InvokeMethod, _
Nothing, ptInstance, New Object() {})
End Sub 'Main
End Class 'AssemblyBuilderDemo
[C#]
using System;
using System.Text;
using System.Threading;
using System.Reflection;
using System.Reflection.Emit;
// The Point class is the class we will reflect on and copy into our
// dynamic assembly. The public static function PointMain() will be used
// as our entry point.
//
// We are constructing the type seen here dynamically, and will write it
// out into a .exe file for later execution from the command-line.
// ---
// class Point {
//
// private int x;
// private int y;
//
// public Point(int ix, int iy) {
//
// this.x = ix;
// this.y = iy;
//
// }
//
// public int DotProduct (Point p) {
//
// return ((this.x * p.x) + (this.y * p.y));
//
// }
//
// public static void PointMain() {
//
// Console.Write("Enter the 'x' value for point 1: ");
// int x1 = Convert.ToInt32(Console.ReadLine());
//
// Console.Write("Enter the 'y' value for point 1: ");
// int y1 = Convert.ToInt32(Console.ReadLine());
//
// Console.Write("Enter the 'x' value for point 2: ");
// int x2 = Convert.ToInt32(Console.ReadLine());
//
// Console.Write("Enter the 'y' value for point 2: ");
// int y2 = Convert.ToInt32(Console.ReadLine());
//
// Point p1 = new Point(x1, y1);
// Point p2 = new Point(x2, y2);
//
// Console.WriteLine("({0}, {1}) . ({2}, {3}) = {4}.",
// x1, y1, x2, y2, p1.DotProduct(p2));
//
// }
//
// }
// ---
class AssemblyBuilderDemo {
public static Type BuildDynAssembly() {
Type pointType = null;
AppDomain currentDom = Thread.GetDomain();
Console.Write("Please enter a name for your new assembly: ");
StringBuilder asmFileNameBldr = new StringBuilder();
asmFileNameBldr.Append(Console.ReadLine());
asmFileNameBldr.Append(".exe");
string asmFileName = asmFileNameBldr.ToString();
AssemblyName myAsmName = new AssemblyName();
myAsmName.Name = "MyDynamicAssembly";
AssemblyBuilder myAsmBldr = currentDom.DefineDynamicAssembly(
myAsmName,
AssemblyBuilderAccess.RunAndSave);
// We've created a dynamic assembly space - now, we need to create a module
// within it to reflect the type Point into.
ModuleBuilder myModuleBldr = myAsmBldr.DefineDynamicModule(asmFileName,
asmFileName);
TypeBuilder myTypeBldr = myModuleBldr.DefineType("Point");
FieldBuilder xField = myTypeBldr.DefineField("x", typeof(int),
FieldAttributes.Private);
FieldBuilder yField = myTypeBldr.DefineField("y", typeof(int),
FieldAttributes.Private);
// Build the constructor.
Type objType = Type.GetType("System.Object");
ConstructorInfo objCtor = objType.GetConstructor(new Type[0]);
Type[] ctorParams = new Type[] {typeof(int), typeof(int)};
ConstructorBuilder pointCtor = myTypeBldr.DefineConstructor(
MethodAttributes.Public,
CallingConventions.Standard,
ctorParams);
ILGenerator ctorIL = pointCtor.GetILGenerator();
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);
// Build the DotProduct method.
Console.WriteLine("Constructor built.");
MethodBuilder pointDPBldr = myTypeBldr.DefineMethod("DotProduct",
MethodAttributes.Public,
typeof(int),
new Type[] {myTypeBldr});
ILGenerator dpIL = pointDPBldr.GetILGenerator();
dpIL.Emit(OpCodes.Ldarg_0);
dpIL.Emit(OpCodes.Ldfld, xField);
dpIL.Emit(OpCodes.Ldarg_1);
dpIL.Emit(OpCodes.Ldfld, xField);
dpIL.Emit(OpCodes.Mul_Ovf_Un);
dpIL.Emit(OpCodes.Ldarg_0);
dpIL.Emit(OpCodes.Ldfld, yField);
dpIL.Emit(OpCodes.Ldarg_1);
dpIL.Emit(OpCodes.Ldfld, yField);
dpIL.Emit(OpCodes.Mul_Ovf_Un);
dpIL.Emit(OpCodes.Add_Ovf_Un);
dpIL.Emit(OpCodes.Ret);
// Build the PointMain method.
Console.WriteLine("DotProduct built.");
MethodBuilder pointMainBldr = myTypeBldr.DefineMethod("PointMain",
MethodAttributes.Public |
MethodAttributes.Static,
typeof(void),
null);
pointMainBldr.InitLocals = true;
ILGenerator pmIL = pointMainBldr.GetILGenerator();
// We have four methods that we wish to call, and must represent as
// MethodInfo tokens:
// - void Console.WriteLine(string)
// - string Console.ReadLine()
// - int Convert.Int32(string)
// - void Console.WriteLine(string, object[])
MethodInfo writeMI = typeof(Console).GetMethod(
"Write",
new Type[] {typeof(string)});
MethodInfo readLineMI = typeof(Console).GetMethod(
"ReadLine",
new Type[0]);
MethodInfo convertInt32MI = typeof(Convert).GetMethod(
"ToInt32",
new Type[] {typeof(string)});
Type[] wlParams = new Type[] {typeof(string), typeof(object[])};
MethodInfo writeLineMI = typeof(Console).GetMethod(
"WriteLine",
wlParams);
// Although we could just refer to the local variables by
// index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
// this time, we'll use LocalBuilders for clarity and to
// demonstrate their usage and syntax.
LocalBuilder x1LB = pmIL.DeclareLocal(typeof(int));
LocalBuilder y1LB = pmIL.DeclareLocal(typeof(int));
LocalBuilder x2LB = pmIL.DeclareLocal(typeof(int));
LocalBuilder y2LB = pmIL.DeclareLocal(typeof(int));
LocalBuilder point1LB = pmIL.DeclareLocal(myTypeBldr);
LocalBuilder point2LB = pmIL.DeclareLocal(myTypeBldr);
LocalBuilder tempObjArrLB = pmIL.DeclareLocal(typeof(object[]));
pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 1: ");
pmIL.EmitCall(OpCodes.Call, writeMI, null);
pmIL.EmitCall(OpCodes.Call, readLineMI, null);
pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
pmIL.Emit(OpCodes.Stloc, x1LB);
pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 1: ");
pmIL.EmitCall(OpCodes.Call, writeMI, null);
pmIL.EmitCall(OpCodes.Call, readLineMI, null);
pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
pmIL.Emit(OpCodes.Stloc, y1LB);
pmIL.Emit(OpCodes.Ldstr, "Enter the 'x' value for point 2: ");
pmIL.EmitCall(OpCodes.Call, writeMI, null);
pmIL.EmitCall(OpCodes.Call, readLineMI, null);
pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
pmIL.Emit(OpCodes.Stloc, x2LB);
pmIL.Emit(OpCodes.Ldstr, "Enter the 'y' value for point 2: ");
pmIL.EmitCall(OpCodes.Call, writeMI, null);
pmIL.EmitCall(OpCodes.Call, readLineMI, null);
pmIL.EmitCall(OpCodes.Call, convertInt32MI, null);
pmIL.Emit(OpCodes.Stloc, y2LB);
pmIL.Emit(OpCodes.Ldloc, x1LB);
pmIL.Emit(OpCodes.Ldloc, y1LB);
pmIL.Emit(OpCodes.Newobj, pointCtor);
pmIL.Emit(OpCodes.Stloc, point1LB);
pmIL.Emit(OpCodes.Ldloc, x2LB);
pmIL.Emit(OpCodes.Ldloc, y2LB);
pmIL.Emit(OpCodes.Newobj, pointCtor);
pmIL.Emit(OpCodes.Stloc, point2LB);
pmIL.Emit(OpCodes.Ldstr, "({0}, {1}) . ({2}, {3}) = {4}.");
pmIL.Emit(OpCodes.Ldc_I4_5);
pmIL.Emit(OpCodes.Newarr, typeof(Object));
pmIL.Emit(OpCodes.Stloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_0);
pmIL.Emit(OpCodes.Ldloc, x1LB);
pmIL.Emit(OpCodes.Box, typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_1);
pmIL.Emit(OpCodes.Ldloc, y1LB);
pmIL.Emit(OpCodes.Box, typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_2);
pmIL.Emit(OpCodes.Ldloc, x2LB);
pmIL.Emit(OpCodes.Box, typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_3);
pmIL.Emit(OpCodes.Ldloc, y2LB);
pmIL.Emit(OpCodes.Box, typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.Emit(OpCodes.Ldc_I4_4);
pmIL.Emit(OpCodes.Ldloc, point1LB);
pmIL.Emit(OpCodes.Ldloc, point2LB);
pmIL.EmitCall(OpCodes.Callvirt, pointDPBldr, null);
pmIL.Emit(OpCodes.Box, typeof(int));
pmIL.Emit(OpCodes.Stelem_Ref);
pmIL.Emit(OpCodes.Ldloc, tempObjArrLB);
pmIL.EmitCall(OpCodes.Call, writeLineMI, null);
pmIL.Emit(OpCodes.Ret);
Console.WriteLine("PointMain (entry point) built.");
pointType = myTypeBldr.CreateType();
Console.WriteLine("Type completed.");
myAsmBldr.SetEntryPoint(pointMainBldr);
myAsmBldr.Save(asmFileName);
Console.WriteLine("Assembly saved as '{0}'.", asmFileName);
Console.WriteLine("Type '{0}' at the prompt to run your new " +
"dynamically generated dot product calculator.",
asmFileName);
// After execution, this program will have generated and written to disk,
// in the directory you executed it from, a program named
// <name_you_entered_here>.exe. You can run it by typing
// the name you gave it during execution, in the same directory where
// you executed this program.
return pointType;
}
public static void Main() {
Type myType = BuildDynAssembly();
Console.WriteLine("---");
// Let's invoke the type 'Point' created in our dynamic assembly.
object ptInstance = Activator.CreateInstance(myType, new object[] {0,0});
myType.InvokeMember("PointMain",
BindingFlags.InvokeMethod,
null,
ptInstance,
new object[0]);
}
}
[C++]
#using <mscorlib.dll>
using namespace System;
using namespace System::Text;
using namespace System::Threading;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
// The Point class is the class we will reflect on and copy into our
// dynamic assembly. The public static function PointMain() will be used
// as our entry point.
//
// We are constructing the type seen here dynamically, and will write it
// out into a .exe file for later execution from the command-line.
// ---
// __gc class Point {
//
// private:
// int x;
// int y;
//
// public:
// Point(int ix, int iy) {
//
// this->x = ix;
// this->y = iy;
//
// }
//
// int DotProduct (Point* p) {
//
// return ((this->x * p->x) + (this->y * p->y));
//
// }
//
// static void PointMain() {
//
// Console::Write(S"Enter the 'x' value for point 1: ");
// int x1 = Convert::ToInt32(Console::ReadLine());
//
// Console::Write(S"Enter the 'y' value for point 1: ");
// int y1 = Convert::ToInt32(Console::ReadLine());
//
// Console::Write(S"Enter the 'x' value for point 2: ");
// int x2 = Convert::ToInt32(Console::ReadLine());
//
// Console::Write(S"Enter the 'y' value for point 2: ");
// int y2 = Convert::ToInt32(Console::ReadLine());
//
// Point* p1 = new Point(x1, y1);
// Point* p2 = new Point(x2, y2);
//
// Console::WriteLine(S"( {0}, {1}) . ( {2}, {3}) = {4}.",
// __box(x1), __box(y1), __box(x2), __box(y2), p1->DotProduct(p2));
//
// }
//
// };
// ---
Type* BuildDynAssembly() {
Type* pointType = 0;
AppDomain* currentDom = Thread::GetDomain();
Console::Write(S"Please enter a name for your new assembly: ");
StringBuilder* asmFileNameBldr = new StringBuilder();
asmFileNameBldr->Append(Console::ReadLine());
asmFileNameBldr->Append(S".exe");
String* asmFileName = asmFileNameBldr->ToString();
AssemblyName* myAsmName = new AssemblyName();
myAsmName->Name = S"MyDynamicAssembly";
AssemblyBuilder* myAsmBldr = currentDom->DefineDynamicAssembly(myAsmName,
AssemblyBuilderAccess::RunAndSave);
// We've created a dynamic assembly space - now, we need to create a module
// within it to reflect the type Point into.
ModuleBuilder* myModuleBldr = myAsmBldr->DefineDynamicModule(asmFileName,
asmFileName);
TypeBuilder* myTypeBldr = myModuleBldr->DefineType(S"Point");
FieldBuilder* xField = myTypeBldr->DefineField(S"x", __typeof(int),
FieldAttributes::Private);
FieldBuilder* yField = myTypeBldr->DefineField(S"y", __typeof(int),
FieldAttributes::Private);
// Build the constructor.
Type* objType = Type::GetType(S"System.Object");
ConstructorInfo* objCtor = objType->GetConstructor(new Type*[0]);
Type* temp4 [] = {__typeof(int), __typeof(int)};
Type* ctorParams[] = temp4;
ConstructorBuilder* pointCtor = myTypeBldr->DefineConstructor(MethodAttributes::Public,
CallingConventions::Standard,
ctorParams);
ILGenerator* ctorIL = pointCtor->GetILGenerator();
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);
// Build the DotProduct method.
Console::WriteLine(S"Constructor built.");
Type* temp0 [] = {myTypeBldr};
MethodBuilder* pointDPBldr = myTypeBldr->DefineMethod(S"DotProduct",
MethodAttributes::Public,
__typeof(int),
temp0);
ILGenerator* dpIL = pointDPBldr->GetILGenerator();
dpIL->Emit(OpCodes::Ldarg_0);
dpIL->Emit(OpCodes::Ldfld, xField);
dpIL->Emit(OpCodes::Ldarg_1);
dpIL->Emit(OpCodes::Ldfld, xField);
dpIL->Emit(OpCodes::Mul_Ovf_Un);
dpIL->Emit(OpCodes::Ldarg_0);
dpIL->Emit(OpCodes::Ldfld, yField);
dpIL->Emit(OpCodes::Ldarg_1);
dpIL->Emit(OpCodes::Ldfld, yField);
dpIL->Emit(OpCodes::Mul_Ovf_Un);
dpIL->Emit(OpCodes::Add_Ovf_Un);
dpIL->Emit(OpCodes::Ret);
// Build the PointMain method.
Console::WriteLine(S"DotProduct built.");
MethodBuilder* pointMainBldr = myTypeBldr->DefineMethod(
S"PointMain",
static_cast<MethodAttributes>(MethodAttributes::Public | MethodAttributes::Static),
__typeof(void),
0);
pointMainBldr->InitLocals = true;
ILGenerator* pmIL = pointMainBldr->GetILGenerator();
// We have four methods that we wish to call, and must represent as
// MethodInfo tokens:
// - void Console::WriteLine(String*)
// - String* Console::ReadLine()
// - int Convert::Int32(String*)
// - void Console::WriteLine(String*, Object*[])
Type* temp1 [] = {__typeof(String)};
MethodInfo* writeMI = __typeof(Console)->GetMethod(S"Write", temp1);
MethodInfo* readLineMI = __typeof(Console)->GetMethod(S"ReadLine", new Type*[0]);
Type* temp2 [] = {__typeof(String)};
MethodInfo* convertInt32MI = __typeof(Convert)->GetMethod(S"ToInt32", temp2);
Type* temp5 [] = {__typeof(String), __typeof(Object*[])};
Type* wlParams[] = temp5;
MethodInfo* writeLineMI = __typeof(Console)->GetMethod(S"WriteLine", wlParams);
// Although we could just refer to the local variables by
// index (short ints for Ldloc/Stloc, bytes for LdLoc_S/Stloc_S),
// this time, we'll use LocalBuilders for clarity and to
// demonstrate their usage and syntax.
LocalBuilder* x1LB = pmIL->DeclareLocal(__typeof(int));
LocalBuilder* y1LB = pmIL->DeclareLocal(__typeof(int));
LocalBuilder* x2LB = pmIL->DeclareLocal(__typeof(int));
LocalBuilder* y2LB = pmIL->DeclareLocal(__typeof(int));
LocalBuilder* point1LB = pmIL->DeclareLocal(myTypeBldr);
LocalBuilder* point2LB = pmIL->DeclareLocal(myTypeBldr);
LocalBuilder* tempObjArrLB = pmIL->DeclareLocal(__typeof(Object*[]));
pmIL->Emit(OpCodes::Ldstr, S"Enter the 'x' value for point 1: ");
pmIL->EmitCall(OpCodes::Call, writeMI, 0);
pmIL->EmitCall(OpCodes::Call, readLineMI, 0);
pmIL->EmitCall(OpCodes::Call, convertInt32MI, 0);
pmIL->Emit(OpCodes::Stloc, x1LB);
pmIL->Emit(OpCodes::Ldstr, S"Enter the 'y' value for point 1: ");
pmIL->EmitCall(OpCodes::Call, writeMI, 0);
pmIL->EmitCall(OpCodes::Call, readLineMI, 0);
pmIL->EmitCall(OpCodes::Call, convertInt32MI, 0);
pmIL->Emit(OpCodes::Stloc, y1LB);
pmIL->Emit(OpCodes::Ldstr, S"Enter the 'x' value for point 2: ");
pmIL->EmitCall(OpCodes::Call, writeMI, 0);
pmIL->EmitCall(OpCodes::Call, readLineMI, 0);
pmIL->EmitCall(OpCodes::Call, convertInt32MI, 0);
pmIL->Emit(OpCodes::Stloc, x2LB);
pmIL->Emit(OpCodes::Ldstr, S"Enter the 'y' value for point 2: ");
pmIL->EmitCall(OpCodes::Call, writeMI, 0);
pmIL->EmitCall(OpCodes::Call, readLineMI, 0);
pmIL->EmitCall(OpCodes::Call, convertInt32MI, 0);
pmIL->Emit(OpCodes::Stloc, y2LB);
pmIL->Emit(OpCodes::Ldloc, x1LB);
pmIL->Emit(OpCodes::Ldloc, y1LB);
pmIL->Emit(OpCodes::Newobj, pointCtor);
pmIL->Emit(OpCodes::Stloc, point1LB);
pmIL->Emit(OpCodes::Ldloc, x2LB);
pmIL->Emit(OpCodes::Ldloc, y2LB);
pmIL->Emit(OpCodes::Newobj, pointCtor);
pmIL->Emit(OpCodes::Stloc, point2LB);
pmIL->Emit(OpCodes::Ldstr, S"( {0}, {1}) . ( {2}, {3}) = {4}.");
pmIL->Emit(OpCodes::Ldc_I4_5);
pmIL->Emit(OpCodes::Newarr, __typeof(Object));
pmIL->Emit(OpCodes::Stloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldc_I4_0);
pmIL->Emit(OpCodes::Ldloc, x1LB);
pmIL->Emit(OpCodes::Box, __typeof(int));
pmIL->Emit(OpCodes::Stelem_Ref);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldc_I4_1);
pmIL->Emit(OpCodes::Ldloc, y1LB);
pmIL->Emit(OpCodes::Box, __typeof(int));
pmIL->Emit(OpCodes::Stelem_Ref);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldc_I4_2);
pmIL->Emit(OpCodes::Ldloc, x2LB);
pmIL->Emit(OpCodes::Box, __typeof(int));
pmIL->Emit(OpCodes::Stelem_Ref);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldc_I4_3);
pmIL->Emit(OpCodes::Ldloc, y2LB);
pmIL->Emit(OpCodes::Box, __typeof(int));
pmIL->Emit(OpCodes::Stelem_Ref);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->Emit(OpCodes::Ldc_I4_4);
pmIL->Emit(OpCodes::Ldloc, point1LB);
pmIL->Emit(OpCodes::Ldloc, point2LB);
pmIL->EmitCall(OpCodes::Callvirt, pointDPBldr, 0);
pmIL->Emit(OpCodes::Box, __typeof(int));
pmIL->Emit(OpCodes::Stelem_Ref);
pmIL->Emit(OpCodes::Ldloc, tempObjArrLB);
pmIL->EmitCall(OpCodes::Call, writeLineMI, 0);
pmIL->Emit(OpCodes::Ret);
Console::WriteLine(S"PointMain (entry point) built.");
pointType = myTypeBldr->CreateType();
Console::WriteLine(S"Type completed.");
myAsmBldr->SetEntryPoint(pointMainBldr);
myAsmBldr->Save(asmFileName);
Console::WriteLine(S"Assembly saved as ' {0}'.", asmFileName);
Console::WriteLine(S"Type ' {0}' at the prompt to run your new dynamically generated dot product calculator.",
asmFileName);
// After execution, this program will have generated and written to disk,
// in the directory you executed it from, a program named
// <name_you_entered_here>.exe. You can run it by typing
// the name you gave it during execution, in the same directory where
// you executed this program.
return pointType;
}
int main() {
Type* myType = BuildDynAssembly();
Console::WriteLine(S"---");
// Let's invoke the type 'Point' created in our dynamic assembly.
Object* temp3 [] = {0, 0};
Object* ptInstance = Activator::CreateInstance(myType, temp3);
myType->InvokeMember(S"PointMain",
BindingFlags::InvokeMethod,
0,
ptInstance,
new Object*[0]);
}
[JScript] JScript のサンプルはありません。Visual Basic、C#、および C++ のサンプルを表示するには、このページの左上隅にある言語のフィルタ ボタン をクリックします。
必要条件
プラットフォーム: Windows 98, Windows NT 4.0, Windows Millennium Edition, Windows 2000, Windows XP Home Edition, Windows XP Professional, Windows Server 2003 ファミリ
.NET Framework セキュリティ:
- FileIOPermission Write = true または Append = true (指定したファイル名にこのアセンブリを保存するために必要)
- ReflectionPermission (Type.InvokeMember などの機構を通じて遅延バインディングで呼び出すときに必要なアクセス許可) ReflectionPermissionFlag.MemberAccess (関連する列挙体)
参照
AssemblyBuilder クラス | AssemblyBuilder メンバ | System.Reflection.Emit 名前空間