You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

peverify校验普通托管代码报无法解析token错误的原因

问题背景

使用 peverify /quiet 工具校验QuickFIXn相关程序集时,遇到如下IL校验错误:

[IL]: Error :[QuickFIXn.xyz.dll : QuickFIXn.MessageFactories+DefaultMessageFactory::GetTransportDataDictionary][offset 0x00000039] Unable to resolve token.

触发错误的托管代码(已省略无关方法、字段定义)

namespace QuickFIXn
{
    public static class MessageFactories
    {
        ...
        internal class DefaultMessageFactory : IMessageFactory
        {
            private readonly System.Collections.Generic.Dictionary<string, IMessageFactory> _factories = new System.Collections.Generic.Dictionary<string, IMessageFactory>();
            ...
            public DataDictionary.DataDictionary GetTransportDataDictionary(string beginString)
            {
                IMessageFactory f;

                // FIXME: This is a hack.  FIXT11 could mean 50 or 50sp1 or 50sp2.
                // We need some way to choose which 50 version it is.
                if (beginString.Equals(FixValues.BeginString.FIXT11))
                {
                    f = _factories["FIX50"];
                } else if (!_factories.TryGetValue(beginString, out f))
                    throw new UnsupportedVersion(beginString);

                return f.GetTransportDataDictionary(beginString);
            }
        }
    }
}

反编译得到的对应方法IL代码

.method public hidebysig newslot virtual final 
        instance class [QuickFIXn]QuickFIXn.DataDictionary.DataDictionary 
        GetTransportDataDictionary(string beginString) cil managed
{
  // code size       63 (0x3f)
  .maxstack  3
  .locals init ([0] class [QuickFIXn]QuickFIXn.IMessageFactory f)
  IL_0000:  ldarg.1
  IL_0001:  ldstr      "FIXT.1.1"
  IL_0006:  callvirt   instance bool [mscorlib]System.String::Equals(string)
  IL_000b:  brfalse.s  IL_0020

  IL_000d:  ldarg.0
  IL_000e:  ldfld      class [mscorlib]System.Collections.Generic.Dictionary`2<string,class [QuickFIXn]QuickFIXn.IMessageFactory> QuickFIXn.MessageFactories/DefaultMessageFactory::_factories
  IL_0013:  ldstr      "FIX50"
  IL_0018:  callvirt   instance !1 class [mscorlib]System.Collections.Generic.Dictionary`2<string,class [QuickFIXn]QuickFIXn.IMessageFactory>::get_Item(!0)
  IL_001d:  stloc.0
  IL_001e:  br.s       IL_0037

  IL_0020:  ldarg.0
  IL_0021:  ldfld      class [mscorlib]System.Collections.Generic.Dictionary`2<string,class [QuickFIXn]QuickFIXn.IMessageFactory> QuickFIXn.MessageFactories/DefaultMessageFactory::_factories
  IL_0026:  ldarg.1
  IL_0027:  ldloca.s   f
  IL_0029:  callvirt   instance bool class [mscorlib]System.Collections.Generic.Dictionary`2<string,class [QuickFIXn]QuickFIXn.IMessageFactory>::TryGetValue(!0,
                                                                                                                                                              !1&)
  IL_002e:  brtrue.s   IL_0037

  IL_0030:  ldarg.1
  IL_0031:  newobj     instance void [QuickFIXn]QuickFIXn.UnsupportedVersion::.ctor(string)
  IL_0036:  throw

  IL_0037:  ldloc.0
  IL_0038:  ldarg.1
  IL_0039:  callvirt   instance class [QuickFIXn]QuickFIXn.DataDictionary.DataDictionary [QuickFIXn]QuickFIXn.IMessageFactory::GetTransportDataDictionary(string)
  IL_003e:  ret
} // end of method DefaultMessageFactory::GetTransportDataDictionary

补充信息

代码中使用的IMessageFactory接口不存在默认接口实现,接口定义如下:

namespace QuickFIXn
{
    public interface IMessageFactory
    {
        DataDictionary.DataDictionary GetTransportDataDictionary(string beginString);
        ...
    }
}
结论

这个报错既不是代码本身有缺陷,也不算peverify的误报,本质是工具和目标程序集的适配问题:

  • 首先可以排除代码问题:逻辑上本地变量f走到0x39位置调用方法前肯定已经被赋值:命中FIXT11分支时会直接从字典取FIX50对应的工厂,key不存在会直接抛KeyNotFoundException,根本走不到后面的调用;走其他版本分支时如果TryGetValue匹配失败会直接抛UnsupportedVersion,只有匹配成功才会给f赋值后走到调用位置,不存在未赋值变量调用的问题。另外已经确认接口没有默认实现、方法确实存在,编译出来的程序集运行是完全正常的。
  • 报错的核心原因是使用的peverify是.NET Framework SDK带的老版本工具,它只支持解析.NET Framework格式的程序集元数据,碰到.NET Core/.NET 5+ 新格式的程序集,就没法正确识别跨程序集的接口方法token,再加上如果运行peverify的时候没把所有依赖的dll放到它的搜索路径里,就会报这个"无法解析token"的错。
  • 要校验新版.NET程序集的IL正确性,不要用老的Framework版peverify,换成.NET SDK自带的dotnet peverify命令即可,合法的代码用新工具校验不会出这个错。

内容的提问来源于stack exchange,提问作者Evgeniy Berezovsky

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.02 01:15:41