1.托管编译器把.cs编译为 CIL,类型元数据,程序集清单。
2.
CIL不允许直接访问一个数据。
为了实现访问,需要显示的加载数据到栈中。并在使用时弹出。
3.
编写.cs
用ildasm打开,并转储为.il
打开.il,并编辑保存
用ilasm编译.il,形成.exe
用peverify从语义上验证.exe.
4.System.Reflection.Emit使得在运行时,创建程序集及其模块,类型定义以及CIL实现逻辑成为可能。
AssemblyBuilder
ModuleBuilder
EnumBuilder
MethodBuilder
LocalBuilder
PropertyBuilder
FieldBuilder
ConstructorBuilder
CustomAttributeBuilder
ParameterBuilder
EventBuilder
EventBuilder
ILGenerator
OpCodes
System.Reflection.Emit.ILGenerator
// ConstructorBuilder myCtorBuilder = new ConstructorBuilder(/**/);
// ILGenerator myCILGen = myCtorBuilder.GetILGenerator();
BeginCatchBlock
BeginExceptionBlock
BeginFinallyBlock
BeginScope
DeclareLocal
DefineLabel
Emit
EmitCall
EmitWriteLine
EndExceptionBlock
EndScope
ThrowException
UsingNamespace
public class Hello
{
private string theMessage;
Hello(){}
Hello(string s){ theMessage = s; }
public string GetMsg(){ return theMessage; }
public void SayHello()
{
System.Console.WriteLine("Hello");
}
public static void CreateMyAsm(AppDomain curAppDomain)
{
AssemblyName assemblyName = new AssemblyName();
assemblyName.Name = "MyAssembly";
assemblyName.Version = new Version("1.0.0.0");
AssemblyBuilder assembly = curAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save);
ModuleBuilder module = assembly.DefineDynamicModule("MyAssembly", "MyAssembly.dll");
TypeBuilder helloClass = module.DefineType("MyAssembly.Hello", TypeAttributes.Public);
FieldBuilder msgField = helloClass.DefineField("theMessage", Type.GetType("System.String"), FieldAttributes.Private);
Type[] constructorArgs = new Type[1];
constructorArgs[0] = typeof(string);
ConstructorBuilder constructor = helloClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs);
ILGenerator constructorIL = constructor.GetILGenerator();
constructorIL.Emit(OpCodes.Ldarg_0);
Type objectClass = typeof(object);
ConstructorInfo superConstructor = objectClass.GetConstructor(new Type[0]);
constructorIL.Emit(OpCodes.Call, superConstructor);
constructorIL.Emit(OpCodes.Ldarg_0);
constructorIL.Emit(OpCodoes.Ldarg_1);
constructorIL.Emit(OpCodes.Stfld, msgField);
constructorIL.Emit(OpCodes.Ret);
helloClass.DefineDefaultConstructor(MethodAttributes.Public);
MethodBuilder getMsgMethod = helloClass.DefineMethod("GetMsg", MethodAttributes.Public, typeof(string), null);
ILGenerator methodIL = getMsgMethod.GetILGenerator();
methodIL.Emit(OpCodes.Ldarg_0);
methodIL.Emit(OpCodes.Ldfld, msgField);
methodIL.Emit(OpCodes.Ret);
MethodBuilder sayHiMethod = helloClass.DefineMethod("SayHello", MethodAttributes.Public, null, null);
methodIL = sayHiMethod.GetILGenerator();
methodIL.EmitWriteLine("Hello from the HelloWrold class!");
methodIL.Emit(OpCodes.Ret);
helloClass.CreateType();
assembly.Save("MyAssembly.dll");
}
static void Main()
{
AppDomain curAppDomain = Thread.GetDomain();
CreateMyAsm(curAppDomain);
Console.WriteLine("->Finished creating MyAssembly.dll");
Assembly a = Assembly.Load("MyAssembly");
Type hello = a.GetType("MyAssembly.HelloWorld");
string msg = Console.ReadLine();
object[] ctorArgs = new object[1];
ctorArgs[0] = msg;
object obj = Activator.CreateInstance(hello, ctorArgs);
MethodInfo mi = hello.GetMethod("SayHello");
mi.Invoke(obj, null);
mi = hello.GetMethod("GetMsg");
Console.WriteLine(mi.Invoke(obj, null));
}
}