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