如何在Mono.Cecil注入的try catch处理程序中多次访问Exception变量?

时间:2014-05-15 16:17:35

标签: c# mono.cecil

我正在使用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);

提前谢谢

1 个答案:

答案 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个小时:-()