我有一个LocalBuilder,它本质上是一个数组。我可以在IL中很好地使用它,我可以使用OpCodes.Ldlen加载它的长度。我只是想知道,是否有任何方法从堆栈顶部到某个实际变量的长度。我在找类似的东西
int lengthVariable = 0;
IL.Emit(OpCodes.Ldloc, arr);
IL.Emit(OpCodes.Ldlen);
IL.Emit(??????, lengthVariable);我希望得到这个变量,这样我就可以根据数组的长度运行一个循环。我知道我可以在IL中创建一个循环,但我认为如果这是可能的话,它会方便得多。
编辑:我想在这里做的是
这方面的问题是,我现在必须调用外部方法两次。我希望我可以从IL数组中获得长度,这样我就可以直接遍历它,而无需两次调用外部方法。我知道我可以用IL编写一个for循环,但我有点避免编写IL的分支语句。
发布于 2020-01-14 16:21:41
您不能这样填充本地lengthVariable --它在一个完全独立的作用域/堆栈框架中运行。但是,您可以更改您的方法(DynamicMethod或MethodBuilder)以返回它,然后将一个委托作为Func<int>创建到您的新方法,并调用它。
然后最后一行是IL.Emit(Opcodes.Ret);,以返回本地堆栈上的单个值。或者,您可以使用Opcodes.Stfld或Opcodes.Stsfld将值存储到实例或静态字段中。
在评论中讨论之后,看来这句话
我知道我可以用IL编写一个for循环,但我有点避免编写IL的分支语句。
在这个问题上,这个问题可能是可以克服的;foreach并不是那么棘手--你所追求的最终IL是可获得的通过反编译现有代码,这使得处理实际分支目标的标签成为唯一棘手的环节--但这仅仅意味着调用.DefineLabel()来声明它们--在您知道它们将跳到哪里之前,就可以将它们作为目标使用--并且只需要.MarkLabel()来定位它们(只有一次)。它不是完全直接的IL (它使用抽象层),但是您可以看到这种方法正在使用这里 --特别是,请注意它提前使用了DefineLabel(),并在MarkLabel后面标记了目的地。
https://stackoverflow.com/questions/59737812
复制相似问题