1. 用到的dynamic CRT版本问题, 通过manifest文件不能很好的分析出来的话,可以通过winSxS以及事件浏览器分析SxS问题. 可以使用dependency walker和ProcessMon工具跟踪程序启动过程发现问题.
SxS错误在WindowsXP和Windows7下的出错提示是不一样的, 但都可以利用利用事件浏览器诊断SideBySide错误.
2. 一个可执行文件用到了多个版本的CRT.
1: <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
2: <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
3: <dependency>
4: <dependentAssembly>
5: <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50727.5592" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
6: </dependentAssembly>
7: </dependency>
8: <dependency>
9: <dependentAssembly>
10: <assemblyIdentity type="win32" name="Microsoft.VC80.DebugCRT" version="8.0.50608.0" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
11: </dependentAssembly>
12: </dependency>
13: </assembly>
我们通过它对应的manifest(清单)文件可以看出来, 这里用到了8.0.50727.5592和8.0.50608.0两个版本的CRT.
NOTE. 简单来说manifest文件标明exe(dll)使用哪个版本的CRT, 解决了不同程序使用不同版本CRT的冲突问题. 这里比较生动的介绍了什么是manifest, 为什么要引入这个概念.
这样在可执行文件中很可能出现一些严重的问题, 导致产生异常致使程序崩溃. 比如a模块使用早些版本的CRT申请资源, 后来b模块使用这些资源并用晚些版本的CRT释放, 很可能释放时出现异常, 原因我不大清楚, 恳请大牛指教.
所以要确保我们的一个可执行文件只能使用一个CRT的统一版本.(可以同时使用不同版本的CRT MFC ATL)
当我们使用了大量的第3方库的时候, 最好保证所有lib dll均由同一编译器版本生成, 否则可能会出现上面的情况. 但是对于以precompiled文件发布的dll我们只能采用其他策略.
这也是我们项目采用的方法: 使用config文件redirect dll版本. 也就是说让不同版本的dll都指向同一版本. 这样做暂时没有发现问题.
例子 XXX.dll.config
1: <configuration>
2: <windows>
3: <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
4: <dependentAssembly>
5: <assemblyIdentity type="win32" name="Microsoft.VC80.CRT.DebugCRT" processorArchitecture="x86" publicKeyToken="1fc8b3b9a1e18e3b"></assemblyIdentity>
6: <bindingRedirect oldVersion="8.0.50608.0-8.0.50727.5592" newVersion="8.0.50727.5592"/>
7: </dependentAssembly>
8: </assemblyBinding>
9: </windows>
10: </configuration>
这里还有些其他的办法.
参考