c# - IlGenerator 发射
问题描述
我正在玩弄DynamicMethod
并尝试使用它IL
来创建一些对象。我想创建以下非常基本的对象:
new Queue<double>(new List<double>{100});
我已经使用 ILDASM 来查看OpCodes
生成它需要什么。这就是 ILDASM 告诉我的:
IL_0000: newobj instance void class [System.Collections]System.Collections.Generic.List`1<float64>::.ctor()
IL_0005: dup
IL_0006: ldc.r8 100.
IL_000f: callvirt instance void class [System.Collections]System.Collections.Generic.List`1<float64>::Add(!0)
IL_0014: newobj instance void class [System.Collections]System.Collections.Generic.Queue`1<float64>::.ctor(class [System.Runtime]System.Collections.Generic.IEnumerable`1<!0>)
IL_0019: pop
IL_001a: ret
这就是我正在做的事情:
var dynMethod = new DynamicMethod("QueueMaker", typeof(Queue<double>), Type.EmptyTypes);
ILGenerator ilGen = dynMethod.GetILGenerator();
ilGen.Emit(OpCodes.Newobj, typeof(List<double>).GetConstructor(Type.EmptyTypes));
ilGen.Emit(OpCodes.Dup);
ilGen.Emit(OpCodes.Ldc_R8, 100);
ilGen.EmitCall(OpCodes.Callvirt, typeof(List<double>).GetMethod("Add"), null);
ilGen.Emit(OpCodes.Newobj, typeof(Queue<double>).GetConstructor(new[] { typeof(IEnumerable<double>) }));
ilGen.Emit(OpCodes.Pop);
ilGen.Emit(OpCodes.Ret);
var returnFunc = (Func<Queue<double>>)dynMethod.CreateDelegate(typeof(Func<Queue<double>>));
var queue = returnFunc();
我得到异常System.InvalidProgramException: 'Common Language Runtime detected an invalid program.'
我做错了什么?
解决方案
我究竟做错了什么?
两件事情:
(1)
ilGen.Emit(OpCodes.Ldc_R8, 100);
这是传递不正确的值类型。确保调用重载double
:
ilGen.Emit(OpCodes.Ldc_R8, (double)100); // or 100d
(2)
ilGen.Emit(OpCodes.Pop);
很可能 ILDASM 包含了这一点,因为在这里new Queue<double>(new List<double>{100});
您要丢弃结果,但是当您需要将结果返回给调用者时,此指令无效。Dup
将新实例保存在评估堆栈上的指令List<double>
已被Queue<double>
构造函数调用消耗,因此这会从堆栈中删除结果,这最终会导致堆栈无效。
删除该行,问题将得到解决。
推荐阅读
- python - 如何在 django 中通过 format_html 返回多个锚点
- python - pyqt 多个对象共享上下文菜单
- api - 是否可以在 facebook 中以编程方式将个人广告帐户链接到企业帐户?
- javascript - 有人可以举一个更真实的例子,其中 setState(updaterFunc) 函数比 setState(object) 更有用吗?
- javascript - am4charts 不适用于时间变量,但它适用于 autoid 变量
- javascript - 如何获得所有文本框的焦点?使用 javascript 事件不使用 jquery
- node.js - Node 生成的子进程何时真正开始?
- angular - 我的角度模板驱动表单中的复选框有一些错误,
- android - 将活动传递给存储库的替代方法
- excel - Excel中的SHA512哈希