4

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

4

1 回答 1

0

Cecil 中有解析二进制 IL 的功能。它在命名空间的类CodeReaderMono.Cecil.Cil。该方法ReadCode或多或少可以满足您的需求。但是这个类的设置方式是你不能只传入一个byte[]. 通常,您需要解析元数据令牌,例如方法调用。CodeReader需要一个MetadataReadervia 构造函数来执行此操作,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();

另一种选择ILReader来自ILVisualizer 2010 解决方案

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);
于 2020-11-23T21:55:50.093 回答