Retrieve code from ILGenerator
Asked Answered
H

2

5

I have write some function to create an exe file using ILGenerator. What I want is to show to user the IL language generated whithout using external tools like ILDasm or Reflector.

during the execution of my program I have added each OpCode to ILGenerator, so I can save each of this OpCode in a list using a string with the OpCode representation but I wish prefer to get the IL code directly. Can it be done?

Important: I'm using Mono 2.6.

Haemachrome answered 22/2, 2012 at 11:18 Comment(1)
Mono.Cecil is the standard answer for these kind of questions.Pandybat
H
3

As Hans Passant and svick had said, the answer is Mono.Cecil. Let's see:

using Mono.Cecil;
using Mono.Cecil.Cil;

[...]


public void Print( ) {
    AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly( this.module_name );

    int i = 0, j = 0;
    foreach ( TypeDefinition t in assembly.MainModule.Types ) {
        if ( t.Name  == "FooClass" ) {
            j = i;
        }
        i++;
    }

    TypeDefinition type = assembly.MainModule.Types[ j ];

    i = j = 0;
    foreach ( MethodDefinition md in type.Methods ) {
        if ( md.Name == "BarMethod" ) {
            j = i;
        }
        i++;
    }

    MethodDefinition foundMethod = type.Methods[ j ];

    foreach( Instruction instr in foundMethod.Body.Instructions ) {
        System.Console.WriteLine( "{0} {1} {2}", instr.Offset, instr.OpCode, instr.Operand );
    }
}

Sure it can be done more efficient but it solves my problem.

Haemachrome answered 23/2, 2012 at 9:12 Comment(1)
I think your code could be easily rewritten to be much more readable using LINQ and Single().Phaeton
P
5

If you have a MethodBuilder, you should be able to use builder.GetMethodBody().GetILAsByteArray() to get the IL as a byte[]. But to make any sense out of that, you would need to parse it somehow.

So, a better choice is probably using Mono Cecil, which can give you the IL code of an assembly in a readable format.

Phaeton answered 22/2, 2012 at 13:12 Comment(0)
H
3

As Hans Passant and svick had said, the answer is Mono.Cecil. Let's see:

using Mono.Cecil;
using Mono.Cecil.Cil;

[...]


public void Print( ) {
    AssemblyDefinition assembly = AssemblyDefinition.ReadAssembly( this.module_name );

    int i = 0, j = 0;
    foreach ( TypeDefinition t in assembly.MainModule.Types ) {
        if ( t.Name  == "FooClass" ) {
            j = i;
        }
        i++;
    }

    TypeDefinition type = assembly.MainModule.Types[ j ];

    i = j = 0;
    foreach ( MethodDefinition md in type.Methods ) {
        if ( md.Name == "BarMethod" ) {
            j = i;
        }
        i++;
    }

    MethodDefinition foundMethod = type.Methods[ j ];

    foreach( Instruction instr in foundMethod.Body.Instructions ) {
        System.Console.WriteLine( "{0} {1} {2}", instr.Offset, instr.OpCode, instr.Operand );
    }
}

Sure it can be done more efficient but it solves my problem.

Haemachrome answered 23/2, 2012 at 9:12 Comment(1)
I think your code could be easily rewritten to be much more readable using LINQ and Single().Phaeton

© 2022 - 2024 — McMap. All rights reserved.