精通C#---CIL和动态程序集作用

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));
    }
}

你可能感兴趣的:(Language-c#)