我正在使用 CodeDOM 动态编译源代码,现在我想使用 Cecil 处理生成的特定方法的 IL 代码,CodeDOM 为我提供了作为字节数组的方法的 IL 代码,有什么方法可以创建 MethodBody, (或者只是一个 Mono.Cecil.Cil.Instruction 数组)来自该字节码而不保存程序集并从那里开始?
问问题
1345 次
1 回答
0
Cecil 中有解析二进制 IL 的功能。它在命名空间的类CodeReader
中Mono.Cecil.Cil
。该方法ReadCode
或多或少可以满足您的需求。但是这个类的设置方式是你不能只传入一个byte[]
. 通常,您需要解析元数据令牌,例如方法调用。CodeReader
需要一个MetadataReader
via 构造函数来执行此操作,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 回答