【问题标题】:DynamicMethod code unverifiable in .Net 4.0 (found ref 'this' pointer... expected ref '<>f__AnonymousType1`).Net 4.0 中无法验证的 DynamicMethod 代码(找到 ref 'this' 指针...预期 ref '<>f__AnonymousType1`)
【发布时间】:2010-07-05 23:21:46
【问题描述】:

正在使用 this solution 将匿名类型转换为使用反射.emit 的字典。在我从 3.5 更改为 .Net 4.0 之前工作正常。

现在,我收到“System.Security.VerificationException:操作可能会破坏运行时”。错误。

将匿名加载的动态方法转换为托管在动态程序集中的方法,保存它,然后在其上运行 peverify.exe 以找出问题所在。

得到:[IL]:错误:[DynamicAssemblyExample.dll:MyDynamicType::MyMethod][offs et 0x0000000D][found ref ('this' ptr) 'MyDynamicType'][expected ref 'f__AnonymousType1`3[System.String,System.Int32,System.Byte]'] stac 上的意外类型 ķ。 [IL]:错误:[DynamicAssemblyExample.dll:MyDynamicType::MyMethod][offs et 0x0000000D] 方法不可见。 2 验证 DynamicAssemblyExample.dll 的错误

代码:

    foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
    {
        // load Dictionary (prepare for call later)
        methIL.Emit(OpCodes.Ldloc_0);

        // load key, i.e. name of the property
        methIL.Emit(OpCodes.Ldstr, property.Name);

        // load value of property to stack
        methIL.Emit(OpCodes.Ldarg_0);
        methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);

        // perform boxing if necessary
        if (property.PropertyType.IsValueType)
        {
            methIL.Emit(OpCodes.Box, property.PropertyType);
        }

        // stack at this point
        // 1. string or null (value)
        // 2. string (key)
        // 3. dictionary

        // ready to call dict.Add(key, value)
        methIL.EmitCall(OpCodes.Callvirt, addMethod, null);

    }

有没有办法取消指向实际属性的指针?还是我必须以某种方式投射它?有什么指点吗?

问候!

【问题讨论】:

    标签: c#-4.0 reflection.emit opcodes


    【解决方案1】:

    对不起,伙计们,犯了一个错误,因为实际的动态方法创建了一个作用于匿名(或非匿名)类型实例的委托类型,Ldarg_0 代码正在寻找此调试中不存在的东西实施。

    所以我把它改成了 OpCodes.Ldnull。

               var attributes = BindingFlags.Instance | BindingFlags.Public | BindingFlags.FlattenHierarchy;
            foreach (PropertyInfo property in itemType.GetProperties(attributes).Where(info => info.CanRead))
            {
                // load Dictionary (prepare for call later)
                methIL.Emit(OpCodes.Ldloc_0);
    
                // load key, i.e. name of the property
                methIL.Emit(OpCodes.Ldstr, property.Name);
    
                // load value of property to stack
                methIL.Emit(OpCodes.Ldnull);
    
                //methIL.Emit(OpCodes.Castclass, itemType);
                methIL.EmitCall(OpCodes.Callvirt, property.GetGetMethod(), null);
    
                // perform boxing if necessary
                if (property.PropertyType.IsValueType)
                {
                    methIL.Emit(OpCodes.Box, property.PropertyType);
                }
    
                // stack at this point
                // 1. string or null (value)
                // 2. string (key)
                // 3. dictionary
    
                // ready to call dict.Add(key, value)
                methIL.EmitCall(OpCodes.Callvirt, addMethod, null);
    
            }
    

    但我仍然得到一个方法不可见的错误后 peverifying 它。是不是通过反射看不到匿名类型属性的 get 方法?

    【讨论】:

      【解决方案2】:

      只是一个建议,您是否尝试过重写发出 IL 以实际写入字典的代码 - 即没有 Reflection.Emit ?我敢打赌,生成的 IL 在某些方面是不正确的,而不是访问匿名类型的代码。

      【讨论】:

      • 是的,我做了一个测试,没有反射,它看起来几乎一样,除了一个 castclass 操作码......这给了我一个想法。
      • 耶,问题解决了。我只需要提出论点,它就奏效了。 .Net 3.5 运行时验证器显然有一些漏洞。感谢您的回复。
      猜你喜欢
      • 1970-01-01
      • 2019-12-23
      • 1970-01-01
      • 2018-08-09
      • 2011-09-05
      • 1970-01-01
      • 2020-12-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多