2

我在使用动态方法时遇到了一些问题。此方法的(伪)IL 代码如下所示

var localB = dynMethodGen.DeclareLocal(typeof(Runtime.IntegerObject));
dynMethodGen.Emit(Ldc_I8, 2);
dynMethodGen.Emit(Newobj, Runtime.IntegerObject.Constructor);
dynMethodGen.Emit(ldstr, "a");
dynMethodGen.Emit(call, GlobalDeclaratorManager.SetMethod);
dynMethodGen.Emit(ldstr, "a");
dynMethodGen.Emit(call, GlobalDeclaratorManager.GetMethod);
dynMethodGen.Emit(Stloc, localB);

使用此代码,我遇到以下问题:最终的 Stloc 导致异常:System.Security.VerificationException: Dieser Vorgang kann die Laufzeit destabilisieren。(在英语中,这意味着运行时可能会不稳定)。

我以前在堆栈不正确时遇到过这个问题,但在这种情况下堆栈是正确的。最后用一个简单的 Pop 替换 Stloc 一切正常,除了该值未存储在语言环境中。

Get 和 Set 方法如下所示:

        public static GenericObject getGlobal(string name)
        {
            return mDeclarators[name];
        }

        public static void setGlobal(GenericObject value, string name)
        {
            mDeclarators[name] = value;
        }

同样有效的方法是将 Stloc 替换为对 SetMethod 的另一个调用,这些值被正确传递。

我错过了某种限制吗?我不能在语言环境中存储函数的返回值吗?

4

1 回答 1

3

你想做的是

setGlobal(new IntegerObject(2), "a");

IntegerObject localB = getGlobal("a");

wheregetGlobal声明返回一个GenericObject实例。

除非类扩展了类,否则您不能将GenericObject实例的引用存储在IntegerObject变量中。C# 编译器会给您以下错误消息:GenericObjectIntegerObject

无法将类型“GenericObject”隐式转换为“IntegerObject”

假设IntegerObjectextends GenericObject,解决方案是添加一个像

IntegerObject localB = (IntegerObject)getGlobal("a");

或者

IntegerObject localB = getGlobal("a") as IntegerObject;
于 2013-04-10T00:18:39.767 回答