Show / Hide Table of Contents

MSDN.WhiteKnight - Stack Overflow answers

Ответ на "Создание конструкции try catch с помощью dnlib"

Answer 1517973

Link

Операндом calli является сигнатура функции, поэтому использовать new Instruction(OpCodes.Calli, null) нельзя. Я заменил calli на nop, попробовал прогнать вашу программу через минимальное консольное приложение ("Hello, world"), и вот что выяснил. Вы добавляете блок catch, но не задаете тип исключений, который надо обрабатывать. Проще всего задать тип Object, чтобы ловить все исключения:

ExceptionHandler item2 = new ExceptionHandler(ExceptionHandlerType.Catch)
{
    HandlerStart = method.Body.Instructions[1],
    HandlerEnd = method.Body.Instructions[method.Body.Instructions.Count - 1],
    TryEnd = method.Body.Instructions[1],
    TryStart = method.Body.Instructions[0],
    CatchType = module.CorLibTypes.Object.TypeRef
};

Если сделать это изменение, попробовать еще раз и прогнать полученную сборку через PEVerify, получаем указание на следующую проблему:

[IL]: Ошибка: [D:...\prog.exe___protected.exe : Prog.Program::Main][смещение 0x0000000C] передача управления в конец блока исключения
Ошибок при проверке: 1 prog.exe___protected.exe

В конце блока обработки исключения должна всегда быть инструкция выхода наружу. То есть чтобы IL был корректен, он должен выглядеть так:

.method public hidebysig static void Main() cil managed
{
 .maxstack  1

 .try
 {
           // Содержимое try        
           leave.s      IL_0001
 }
 catch [mscorlib]System.Exception
 {
           // Содержимое catch  
           leave.s      IL_0001
 }
 IL_0001: ret          
}

Это в самом простом случае, когда метод не имеет возвращаемого значения. Если метод возвращает значение, перед ret еще должна быть инструкция, загружающие это значение на стек. Подробнее об инструкциях и как они работают можно узнать в спецификации ECMA-335, третий раздел.


Content is retrieved from StackExchange API.

Auto-generated by ruso-archive tools.

Back to top Stack Overflow answers (published from sources in GitHub repository). Copyright (c) 2020, MSDN.WhiteKnight. Content licensed under BSD 3-Clause License.
Generated by DocFX