2017-01-16 18 views
4

Я начал переписывать свой Function Plotter, который выполняет математическую функцию и вычисляет значение y для заданного x. Чтобы перезаписать его, я хочу динамически создать метод с использованием IL. Тест-код IL, который у меня есть, теперь использует 2 LocalBuilders и умножает их. Однако, когда я возвращаю значение, я получаю (то, что кажется) случайным числом вместо реального ответа.IL Возврат в C# возвращает неправильное значение

Вот код, который я использовал.

 ILGenerator il = hello.GetILGenerator(); 

     LocalBuilder a = il.DeclareLocal(typeof(int)); 
     LocalBuilder b = il.DeclareLocal(typeof(int)); 
     LocalBuilder multOfAandB = il.DeclareLocal(typeof(int)); 

     il.Emit(OpCodes.Ldc_I4, 5); // Store "5" ... 
     il.Emit(OpCodes.Stloc, a); // ... in "a". 

     il.Emit(OpCodes.Ldc_I4, 6); // Store "6" ... 
     il.Emit(OpCodes.Stloc, b); // ... in "b". 

     il.Emit(OpCodes.Ldloc, a); 
     il.Emit(OpCodes.Ldloc, b); 

     il.Emit(OpCodes.Mul);  // Multiply them ... 
     il.Emit(OpCodes.Ret);  // ... and return the result. 

Это должно вернуть 30, но в настоящее время я получаю 4.2038953929744512E-44. Что-то не так с моим кодом, что заставляет функцию возвращать неправильное значение?

Заранее спасибо

EDIT

Код вызова функции выглядит следующим образом:

 object[] invokeArgs = { 42 }; 
     object obj = func.helloMethod.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us")); 

и в моем классе, где я хранить функцию, чтобы позже вызвать из меню FUNC. helloMethod имеет DynamicMethod, который определяется следующим образом:

DynamicMethod hello = new DynamicMethod("Hello", 
      typeof(double), 
      helloArgs, 
      typeof(double).Module); 
+0

выглядит хорошо ... как вы извлекаете и показываете результат (особенно, что происходит с 'multOfAandB'?), Я бы заподозрил проблему с исполнением, а не с той частью кода. Случайное число будет неинициализированной памятью. – dlatikay

+0

@dlatikay из моего основного Я вызываю 'object [] invokeArgs = {42}; объект obj = func.helloMethod.Invoke (null, BindingFlags.ExactBinding, null, invokeArgs, новый CultureInfo («en-us»)); где мой динамический метод «DynamicMethod hello = new DynamicMethod (« Hello », typeof (double), helloArgs, typeof (double) .Module); «Я сохраняю свой DynamicMethod в общедоступной переменной, которую я вызываю из своей основной + – Felix

+0

, мы можем предположить, что остальная часть вызывающего кода построена аналогично [this] (https://msdn.microsoft.com/en-us /library/csx7wsz2(v=vs.110).aspx); и ваш 42 никогда не Ldarg_0'ed - все еще подозревая проблему звонящего/вызываемого здесь – dlatikay

ответ

3

Кажется, вы случайно пытаетесь вернуть возвращаемое значение от int до double. Динамическое выполнение удивительно отказоустойчиво здесь, похоже, нет проверки на несоответствие типов.

Изменить код вызова в соответствии с типами данных внутренних местных жителей:

var hello = new DynamicMethod(
    "Hello", 
    typeof(int), 
    helloArgs, 
    typeof(YourClassNameHere).Module 
); 

Обратите внимание, что тип в последний аргумент должен быть имя вашего класса, не то типа аргумента данных.

+0

CLR - размерная королева. Он больше заботится о размере переменных, чем их тип (если вы не делаете вызов виртуального метода, но даже тогда ...) – hoodaticus

1

Проблема здесь было определение DynamicMethod:

DynamicMethod hello = new DynamicMethod("Hello", 
     typeof(double), 
     helloArgs, 
     typeof(double).Module); 

С 6 * 5 возвращает 30, который является INT, это были проблемы, изменяющие Int к двойной и возвратите неправильный ответ. Как только я изменил его на typeof (int), возвращаемое значение было 30. Я понятия не имел, что IL был таким особенным в типе.