【问题标题】:Get type stored in binary field signature获取存储在二进制字段签名中的类型
【发布时间】:2015-01-28 03:21:54
【问题描述】:

假设您在 .NET 模块中有字段签名的二进制表示,例如 0604。 6 (FIELD) 代表字段调用约定,4 (ELEMENT_TYPE_I1) 代表 I1 原始类型(有关 CIL 的更多信息,请参见 ECMA-335)。签名可以来自调试器或程序集检查器,这并不重要。更重要的是,是否有可能(使用 .NET 提供的方法)“解析”这个签名并获得该签名所代表的对应 .NET 类型?

例子:

0601System.Void
0604System.SByte
060ESystem.String
061408020000System.Int32[,]

【问题讨论】:

    标签: c# .net reflection clr cil


    【解决方案1】:

    我不知道有任何公共 API 可以做到这一点,但 Cecil 可以在内部解析这种签名,所以你可以复制它的代码。

    相关代码在SignatureReader.ReadTypeSignature()

    或者也许不要尝试自己解析程序集并使用 Cecil。

    【讨论】:

      【解决方案2】:

      有一些内部 .NET 方法可以做到这一点:

      public static unsafe Type GetTypeFromFieldSignature(byte[] signature, Type declaringType = null)
      {
          declaringType = declaringType ?? typeof(object);
          Type sigtype = typeof(Type).Module.GetType("System.Signature");
          Type rtype = typeof(Type).Module.GetType("System.RuntimeType");
          var ctor = sigtype.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, new[]{typeof(void*), typeof(int), rtype}, null);
          fixed(byte* ptr = signature)
          {
              object sigobj = ctor.Invoke(new object[]{(IntPtr)ptr, signature.Length, declaringType});
              return (Type)sigtype.InvokeMember("FieldType", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.GetProperty, null, sigobj, null);
          }
      }
      

      这会加载任何有效的字段签名并返回适当的类型。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-10-05
        • 2020-10-31
        • 1970-01-01
        • 1970-01-01
        • 2021-06-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多