gpt4 book ai didi

c# - IlGenerator 发射

转载 作者:太空宇宙 更新时间:2023-11-03 20:52:37 27 4
gpt4 key购买 nike

我正在尝试使用 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.' 我做错了什么?

最佳答案

What am I doing wrong?

两件事:

(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> 使用构造函数调用,因此这会从堆栈中删除结果,这最终会导致堆栈无效。

去掉那一行,问题就解决了。

关于c# - IlGenerator 发射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53716931/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com