【问题标题】:How to access the Exception variable more than once in an injected try catch handler with Mono.Cecil?如何使用 Mono.Cecil 在注入的 try catch 处理程序中多次访问 Exception 变量?
【发布时间】:2014-05-16 04:23:00
【问题描述】:

我正在使用 Mono.Cecil 在方法主体周围添加一个 try catch 块

一切进展顺利,即使我可以在 catch 块中使用捕获的异常 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);

提前谢谢

【问题讨论】:

    标签: c# mono.cecil


    【解决方案1】:

    我终于找到了答案。 关键是定义一个自己的变量,并在 catch 块的第一条指令中将 eval 堆栈的顶部存储在这个 var 中:

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

    【讨论】:

      猜你喜欢
      • 2012-09-27
      • 2013-02-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-17
      • 1970-01-01
      • 2012-02-01
      • 2013-04-27
      相关资源
      最近更新 更多