Free mag vol1 | Page 717

CHAPTER 18  UNDERSTANDING CIL AND THE ROLE OF DYNAMIC ASSEMBLIES } ldstr "Hello CIL code!" call void [mscorlib]System.Console::WriteLine(string) nop call string [mscorlib]System.Console::ReadLine() pop ret Interacting with CIL: Modifying an *.il File Now that you have a better understanding of how a basic CIL file is composed, let’s complete the roundtripping experiment. The goal here is to update the CIL within the existing *.il file as follows: • Add a reference to the System.Windows.Forms.dll assembly. • Load a local string within Main(). • Call the System.Windows.Forms.MessageBox.Show() method using the local string variable as an argument. The first step is to add a new .assembly directive (qualified with the extern attribute) that specifies your assembly requires the System.Windows.Forms.dll assembly. To do so, update the *.il file with the following logic after the external reference to mscorlib: .assembly extern System.Windows.Forms { .publickeytoken = (B7 7A 5C 56 19 34 E0 89) .ver 4:0:0:0 } Be aware that the value assigned to the .ver directive may differ depending on which version of the .NET platform you have installed on your development machine. Here, you see that System.Windows.Forms.dll version 4.0.0.0 is used and has the public key token of B77A5C561934E089. If you open the GAC (see Chapter 14) and locate your version of the System.Windows.Forms.dll assembly, you can simply copy the correct version and public key token value. Next, you need to alter the current implementation of the Main() method. Locate this method within the *.il file and remove the current implementation code (the .maxstack and .entrypoint directives should remain intact), like so: .method private hidebysig static void { .entrypoint .maxstack 8 // ToDo: Write new CIL code! } Main(string[] args) cil managed Again, the goal here is to push a new string onto the stack and call the MessageBox.Show() method (rather than the Console.WriteLine() method). Recall that when you specify the name of an external type, you must make use of the type’s fully qualified name (in conjunction with the friendly name of the assembly). Also notice that in terms of CIL, every method call documents the fully qualified return type. Keeping these things in mind, update the Main() method as follows: 660