C# 中的 IL Return returns 错误值
IL Return in C# returns wrong value
我开始重写我的函数绘图仪,它采用数学函数并计算给定 x 的 y 值。要重写它,我想使用 IL 动态创建一个方法。我现在拥有的测试 IL 代码使用 2 个 LocalBuilder 并将它们相乘。然而,当我 return 这个值时,我收到(似乎是)一个随机数而不是真正的答案。
下面是我一直在使用的代码。
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.
这应该是 return 30,但目前我收到的是 4.2038953929744512E-44。我的代码有什么问题导致函数 return 错误值吗?
提前致谢
编辑
调用函数的代码如下:
object[] invokeArgs = { 42 };
object obj = func.helloMethod.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us"));
在我的 class 中,我存储函数以便稍后从 func.helloMethod 调用它的地方有一个 DynamicMethod,其定义如下:
DynamicMethod hello = new DynamicMethod("Hello",
typeof(double),
helloArgs,
typeof(double).Module);
您似乎不小心将 return 值从 int
强制转换为 double
。
这里的动态执行令人惊讶fault-tolerant,似乎没有检查类型不匹配。
更改调用代码以匹配内部局部变量的数据类型:
var hello = new DynamicMethod(
"Hello",
typeof(int),
helloArgs,
typeof(YourClassNameHere).Module
);
请注意,最后一个参数中的类型应该是您的 class 名称,而不是参数数据类型的名称。
这里的问题是 DynamicMethod 的定义:
DynamicMethod hello = new DynamicMethod("Hello",
typeof(double),
helloArgs,
typeof(double).Module);
因为 6 * 5 returns 30 是一个 int,所以将 int 更改为 double 时出现问题并返回了错误的答案。改成typeof(int)后,返回值是30,没想到IL对类型这么讲究
我开始重写我的函数绘图仪,它采用数学函数并计算给定 x 的 y 值。要重写它,我想使用 IL 动态创建一个方法。我现在拥有的测试 IL 代码使用 2 个 LocalBuilder 并将它们相乘。然而,当我 return 这个值时,我收到(似乎是)一个随机数而不是真正的答案。
下面是我一直在使用的代码。
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.
这应该是 return 30,但目前我收到的是 4.2038953929744512E-44。我的代码有什么问题导致函数 return 错误值吗?
提前致谢
编辑
调用函数的代码如下:
object[] invokeArgs = { 42 };
object obj = func.helloMethod.Invoke(null, BindingFlags.ExactBinding, null, invokeArgs, new CultureInfo("en-us"));
在我的 class 中,我存储函数以便稍后从 func.helloMethod 调用它的地方有一个 DynamicMethod,其定义如下:
DynamicMethod hello = new DynamicMethod("Hello",
typeof(double),
helloArgs,
typeof(double).Module);
您似乎不小心将 return 值从 int
强制转换为 double
。
这里的动态执行令人惊讶fault-tolerant,似乎没有检查类型不匹配。
更改调用代码以匹配内部局部变量的数据类型:
var hello = new DynamicMethod(
"Hello",
typeof(int),
helloArgs,
typeof(YourClassNameHere).Module
);
请注意,最后一个参数中的类型应该是您的 class 名称,而不是参数数据类型的名称。
这里的问题是 DynamicMethod 的定义:
DynamicMethod hello = new DynamicMethod("Hello",
typeof(double),
helloArgs,
typeof(double).Module);
因为 6 * 5 returns 30 是一个 int,所以将 int 更改为 double 时出现问题并返回了错误的答案。改成typeof(int)后,返回值是30,没想到IL对类型这么讲究