我正在使用Mono.Cecil
添加一个围绕方法体的try catch块一切顺利,即使我可以在catch块中使用捕获的Exception exception1参数调用方法,因为似乎exception1值位于堆栈顶部。
然而,在调用之后,该值将从堆栈中删除,如果我想使用exception1作为参数调用另一个方法,我无法弄清楚如何在调用之前访问它ldloc。
所以下面的代码正在运行,我只是不知道如何使用捕获的异常值作为参数调用catch块中的其他方法。
var statementInTheCatchBlock = il.Create(OpCodes.Call, module.Import(typeof(AnyType).GetMethod("AnyMethod", new[] { typeof(Exception) })));
var ret = il.Create(OpCodes.Ret);
var leave = il.Create(OpCodes.Leave, ret);
il.InsertAfter(method.Body.Instructions.Last(), statementInTheCatchBlock);
il.InsertAfter(statementInTheCatchBlock, leave);
il.InsertAfter(leave, ret);
var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
TryStart = method.Body.Instructions.First(),
TryEnd = statementInTheCatchBlock,
HandlerStart = statementInTheCatchBlock,
HandlerEnd = ret,
CatchType = module.Import(typeof(Exception)),
};
method.Body.ExceptionHandlers.Add(handler);
提前谢谢
答案 0 :(得分:0)
最后,我设法找到了答案。 关键是定义一个自己的变量,并在catch块的第一条指令中存储此var中eval堆栈的顶部:
var exceptionVariable = new VariableDefinition("e", method.Module.Import(typeof (Exception)));
method.Body.Variables.Add(exceptionVariable);
var last = method.Body.Instructions.Last();
Instruction tryEnd;
il.InsertAfter(last, tryEnd = last = il.Create(OpCodes.Stloc_S, exceptionVariable));
il.InsertAfter(last, last = il.Create(OpCodes.Ldloc_S, exceptionVariable));
il.InsertAfter(last, last = anyCallInstructionWithExceptionParamter);
il.InsertAfter(last, last = il.Create(OpCodes.Ldloc_S, exceptionVariable));
il.InsertAfter(last, last = otherCallInstructionWithExceptionParamter);
il.InsertAfter(last, last = leave);
il.InsertAfter(last, ret);
var handler = new ExceptionHandler(ExceptionHandlerType.Catch)
{
TryStart = method.Body.Instructions.First(),
TryEnd = tryEnd,
HandlerStart = tryEnd,
HandlerEnd = ret,
CatchType = module.Import(typeof (Exception)),
};
感谢所有花时间的人(对我来说这是3个小时:-()