如何使用Mono.Cecil从字节数组中解析IL指令

时间:2013-04-24 11:56:21

标签: c# mono.cecil

我使用CodeDOM动态编译源代码, 现在我想使用Cecil处理特定方法生成的IL代码,CodeDOM为我提供了方法的IL代码作为字节数组,有没有办法创建一个MethodBody,(或者只是一个Mono.Cecil数组) .Cil.Instruction)从那个字节码而不保存程序集并从那里开始?

1 个答案:

答案 0 :(得分:0)

Cecil中具有解析二进制IL的功能。它位于Mono.Cecil.Cil命名空间的CodeReader类中。 方法ReadCode或多或少地完成了您想要的操作。但是,该类的设置方式不能只传递byte[]。通常,您需要解析元数据令牌,例如用于方法调用。 CodeReader需要通过构造函数的MetadataReader来完成此操作,而MetadataReader则需要一个ModuleDefinition


如果不使用Cecil,还有另一种选择。使用SDILReader

// get the method that you want to extract the IL from
MethodInfo methodInfo = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic);

Globals.LoadOpCodes();

// doesn't work on DynamicMethod
MethodBodyReader reader = new MethodBodyReader(methodInfo);
List<ILInstruction> instructions = reader.instructions;
string code = reader.GetBodyCode();

另一种选择是ILVisualizer 2010 Solution中的ILReader

DynamicMethod dynamicMethod = new DynamicMethod("HelloWorld", typeof(void), new Type[] { }, typeof(Program), false);

ILGenerator ilGenerator = dynamicMethod.GetILGenerator();
ilGenerator.Emit(OpCodes.Ldstr, "hello, world");       
ilGenerator.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));
ilGenerator.Emit(OpCodes.Ret);

MethodBodyInfo methodBodyInfo = MethodBodyInfo.Create(dynamicMethod);
string ilCode = string.Join(Environment.NewLine, methodBodyInfo.Instructions);

// get the method that you want to extract the IL from
MethodInfo methodInfo = typeof(Foo).GetMethod("Bar", BindingFlags.Static | BindingFlags.NonPublic);
MethodBodyInfo methodBodyInfo2 = MethodBodyInfo.Create(methodInfo);
string ilCode2 = string.Join(Environment.NewLine, methodBodyInfo2.Instructions);