IL preliminary understanding, preliminary understanding of English

Source: Internet
Author: User
Tags emit reflector

IL preliminary understanding, preliminary understanding of English

 

I. Overview:

Recently, I have been looking at AOP and learned that Emit can be implemented. Previous knowledge of Emit is part of the commands decompiled by Reflector. I will use this opportunity to learn the learning process of Emit. I also hope you can give me some guidance in some areas I don't know.

You can learn about Opcodes before learning.

Ii. Tools

1. vs2015

2.. NET Reflector 9.0

Iii. Example

1. Output Hello World

C # code

        static void Main(string[] args)        {            Console.WriteLine("Hello world!");        }
View Code

Decompile the obtained IL code

Emit implementation code

Public void HellowWorld () {// defines the Hellow method. No return value. No parameter. DynamicMethod helloWorldMethod = new DynamicMethod ("HellowWorld", null, null). // creates an IL, dynamically generated code ILGenerator IL = helloWorldMethod. getILGenerator (); // pushes the output to the stack IL. emit (OpCodes. ldstr, "Hello World! "); // Execute Console. writeLine IL. emit (OpCodes. call, typeof (Console ). getMethod ("WriteLine", new Type [] {typeof (string)}); // The method ends IL. emit (OpCodes. ret); HelloWordDelegate Method = (HelloWordDelegate) helloWorldMethod. createDelegate (typeof (HelloWordDelegate); Method ();}
View Code

The request is being called. If a parameter exists, the system prompts "the operation may damage the runtime stability ". (Not clear)

4. Build an assembly

1. The following describes how to create an instance by constructing a class that contains two methods.

        public int Add(int a, int b)        {            return a + b;        }        public string AddList(string[] array)        {            string result = string.Empty;            for (int i = 0; i < array.Length; i++)            {                result = result + array[i];            }            return result;        }
View Code

2. Check the IL code decompiled by the two methods.

Next, let's take a look at how IL is implemented.

● L0000 to L0009: Assign string. Empty to the custom variable resultName, load the integer 0, L0009 to jump to L001b for execution
● L001b to L0027: load 1 index value, load parameter 1 (Static starting from 0), Ldlen pushes the number of arrays from 0 to the stack, and compares the size of the two values, (store the comparison result at index 2, and then retrieve it (this step can be omitted), and then jump to L_000b for execution.
● L000b to L001a: load the index value at 0, and load parameter 1. Ldelem_Ref is used to load string-type Elements and execute string. the concat method stores the value at index 0, loads the value at Index 1, loads the integer 1, adds the two values, and stores the value at index 0.
● L002a end return

3. The following is implemented through Emit code:

Public void GenerateAssembly () {string name = "IL. dynamic "; string fileName = string. format ("{0 }. dll ", name); // build Assembly AssemblyName assemblyName = new AssemblyName (name); // application Assembly domain AppDomain domain = AppDomain. currentDomain; // instantiate an AssemblyBuilder object to construct a dynamic assembly AssemblyBuilder assemblyBuilder = domain. defineDynamicAssembly (assemblyName, AssemblyBuilderAccess. runAndSave); // defines the module (without filename being a transient module, not persistent) ModuleBuilder moduleBuilder = assemblyBuilder. defineDynamicModule (name); // define the type TypeBuilder typeBuilder = moduleBuilder. defineType (name, TypeAttributes. public); // define an Add method to simply Add MethodBuilder methodBuilder = typeBuilder. defineMethod ("Add", MethodAttributes. public, typeof (Int32), new Type [] {typeof (int), typeof (int)}); // IL implements ILGenerator IL = methodBuilder. getILGenerator (); IL. emit (OpCodes. ldarg_1); IL. emit (OpCodes. ldarg_2); IL. emit (OpCodes. add); IL. emit (OpCodes. ret); // defines an AddList string using the for concatenation method MethodBuilder method2Builder = typeBuilder. defineMethod ("AddList", MethodAttributes. public | MethodAttributes. static, typeof (string), new Type [] {typeof (string [])}); FieldBuilder fieldName = typeBuilder. defineField ("resultName", typeof (string), FieldAttributes. private | FieldAttributes. static); ILGenerator addIL = method2Builder. getILGenerator (); // local variable used to save the sum result LocalBuilder resultStr = addIL. declareLocal (typeof (String); // The local variable LocalBuilder I = addIL used in the loop. declareLocal (typeof (Int32); Label concatLabel = addIL. defineLabel (); Label LoopLabel = addIL. defineLabel (); // set string result = string. empty; addIL. emit (OpCodes. ldsfld, fieldName); addIL. emit (OpCodes. stloc_0); // set I = 0 addIL. emit (OpCodes. ldc_I4_0); addIL. emit (OpCodes. stloc_1); addIL. emit (OpCodes. br, concatLabel); // enter the loop body addIL. markLabel (LoopLabel); addIL. emit (OpCodes. ldloc_0); // The parameter specifies that the static state starts from 0 addIL. emit (OpCodes. ldarg_0); addIL. emit (OpCodes. ldloc_1); // Ldelem_Ref is used to load the string type element addIL. emit (OpCodes. ldelem_Ref); addIL. emit (OpCodes. call, typeof (string ). getMethod ("Concat", new Type [] {typeof (string), typeof (string)}); addIL. emit (OpCodes. stloc_0); addIL. emit (OpCodes. ldloc_1); // I ++ addIL. emit (OpCodes. ldc_I4_1); addIL. emit (OpCodes. add); addIL. emit (OpCodes. stloc_1); addIL. markLabel (concatLabel); addIL. emit (OpCodes. ldloc_1); addIL. emit (OpCodes. ldarg_0); addIL. emit (OpCodes. ldlen); addIL. emit (OpCodes. conv_I4); // Clt compare the two values of addIL. emit (OpCodes. clt); addIL. emit (OpCodes. brtrue_S, LoopLabel); addIL. emit (OpCodes. ldloc_0); addIL. emit (OpCodes. ret); Type type = typeBuilder. createType (); assemblyBuilder. save (fileName); int [] ints = new int [] {1, 2, 3, 4}; string [] array = new string [] {"", "B", "c"}; object ob = Activator. createInstance (type); var result = type. getMethod ("Add "). invoke (ob, new object [] {8, 9}); var result1 = type. getMethod ("AddList "). invoke (ob, new object [] {array });}
View Code

3.1 AssemblyBuilderAccess

Run It can be executed but cannot be saved
Save Save but cannot execute
RunAndSave Can be executed and saved
ReflectionOnly Load only in reflection Context

 

 

 

 

4. Running output

4.1 generate a file

View the C # code generated by IL by decompiling with tools

4.2 running results

Through this example, we can have a basic understanding of IL, and continue to talk with you later. Download System. IL from the project

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.