2012-02-22 27 views
5

Tôi đã viết một số chức năng để tạo tệp exe bằng cách sử dụng ILGenerator. Những gì tôi muốn là hiển thị cho người dùng ngôn ngữ IL tạo ra whithout bằng cách sử dụng các công cụ bên ngoài như ILDasm hoặc Reflector.Lấy mã từ ILGenerator

trong khi thực hiện chương trình, tôi đã thêm từng mã Opcode vào ILGenerator, vì vậy tôi có thể lưu từng mã OpCode này trong danh sách bằng cách sử dụng chuỗi ký tự đại diện OpCode nhưng tôi muốn lấy mã IL trực tiếp. Nó có thể được thực hiện?

Quan trọng: Tôi đang sử dụng Mono 2.6.

+3

Mono.Cecil là câu trả lời tiêu chuẩn cho các loại câu hỏi này. –

Trả lời

3

Hans Passantsvick đã nói, câu trả lời là Mono.Cecil. Hãy xem:

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

Chắc chắn nó có thể được thực hiện hiệu quả hơn nhưng nó giải quyết được vấn đề của tôi.

+0

Tôi nghĩ rằng mã của bạn có thể dễ dàng viết lại để dễ đọc hơn nhiều bằng cách sử dụng LINQ và 'Single()'. – svick

5

Nếu bạn có số MethodBuilder, bạn sẽ có thể sử dụng builder.GetMethodBody().GetILAsByteArray() để nhận số IL là byte[]. Nhưng để làm cho bất kỳ ý nghĩa ra khỏi đó, bạn sẽ cần phải phân tích nó bằng cách nào đó.

Vì vậy, lựa chọn tốt hơn có thể là sử dụng Mono Cecil, có thể cung cấp cho bạn mã IL của một hội đồng ở định dạng có thể đọc được.