2013-08-11 5 views
1

Сегодня я начал изучать класс DynamicMethod. В целях обучения я решил использовать DynamicMethod для создания функции, которая не принимает аргумента и всегда возвращает логическое значение true.Получение ошибки при попытке использовать DynamicMethod для создания метода, который всегда возвращает true

Я создал функцию для этого в C#, а затем рассмотрел полученный IL-код с помощью Telerik JustDecompile.

.method public hidebysig instance bool ReturnTrue1() cil managed 
{ 
    .locals init (
     [0] bool CS$1$0000 
    ) 

    IL_0000: nop 
    IL_0001: ldc.i4.1 
    IL_0002: stloc.0 
    IL_0003: br.s IL_0005 

    IL_0005: ldloc.0 
    IL_0006: ret 
} 

Это выглядит достаточно просто. Согласно документации, похоже, что эти инструкции просто помещают целое число 1 в стек, который должен быть возвращен.

Следуя приведенным ниже примерам, я написал следующее консольное приложение.

using System; 
using System.Reflection.Emit; 

namespace EntityFrameworkDynamicMethod 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     {    
      ReturnTrue ReturnTrueDelegate = GetReturnTrueDelegate(); 
      ReturnTrueDelegate();    
     }   

     delegate bool ReturnTrue(); 

     static ReturnTrue GetReturnTrueDelegate() 
     {    
      DynamicMethod method = new DynamicMethod("ReturnTrue", typeof(bool), new Type[] {}); 
      ILGenerator generator = method.GetILGenerator(); 
      Label IL_0005 = generator.DefineLabel(); 
      generator.Emit(OpCodes.Nop); 
      generator.Emit(OpCodes.Ldc_I4_1); 
      generator.Emit(OpCodes.Stloc_0);    
      generator.Emit(OpCodes.Ldloc_0, IL_0005);    
      generator.MarkLabel(IL_0005); 
      generator.Emit(OpCodes.Ret); 

      return (ReturnTrue)method.CreateDelegate(typeof(ReturnTrue)); 
     } 
    } 
} 

Однако, когда я запускаю этот код, следующее исключение возбуждается на ReturnTrueDelegate();

System.Security.VerificationException: Operation could destabilize the runtime. 
at ReturnTrue() 

Что это означает исключение и что мне делать, чтобы исправить это?

ответ

4
generator.Emit(OpCodes.Ldloc_0, IL_0005); 

Это неправильное изображение; инструкция ldloc.0 не имеет аргументов (вы имели в виду br.s?).
Вы также не можете использовать локальные 0, не объявляя об этом.

Однако вам это не нужно; все, что вам нужно сделать, это загрузить 1 (ldc.i4.1) и вернуть его (ret).
Если вы декомпилируете код режима освобождения, вы должны это увидеть.

+0

А, да, я декомпилировался в режиме DEBUG. Я не думал сначала отпустить его. –

 Смежные вопросы

  • Нет связанных вопросов^_^