MSDN.WhiteKnight - Stack Overflow answers
Ответ на "Создание конструкции try catch с помощью dnlib"
Answer 1517973
Операндом 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.