面对系统中多个版本的VC运行时库,应用程序如何选择

本文探讨了在存在多个版本的VC运行时库时,如何确定正确的版本以确保应用程序正常运行。通过创建一个简单的C++程序并分析其依赖关系,揭示了系统如何选择兼容的运行时库版本。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

 

目的:

探究采用VC运行时库生成的应用程序,当系统中存在多个版本的VC运行时库,如何查找正确的版本,来保证程序的正常执行。

环境:

本文使用的开发环境为Visual Studio2005,语言为C++,使用VC运行时库来生成应用程序。

必备工具:

Dependency Walker

正文:

本人现在所用Windows XP系统中有两个版本的VC运行时库分别是CRT8.0.50727.42CRT8.0.50727. 4053,其位于目录“C:/WINDOWS/WinSxS/”下。下面来生成一个使用了VC运行时库的小程序。

建立一个名为test.cppC++源文件,如下:

打开VS2005自带的命令行工具,输入编译命令:

cl -nologo -c -EHsc -MD -Fotest.obj test.cpp

命令执行完后生成一个名为test.obj的文件,编译选项中-MD表示采用多线程DLL的方式使用VC运行时库。再输入连接命令:

link -nologo -manifest -manifestfile:test.intermediate.manifest -OUT:test.exe test.obj

命令执行完后,可以看到生成了一个名为“test.intermediate.manifest”的清单文件以及“test.exe”的可执行文件。test.intermediate.manifes其实是一个XML文本文件,其内容如下:

 

       很显然其中指明了所依赖的VC运行时库的版本为8.0.50608.0。再继续输入命令:

mt -nologo -manifest test.intermediate.manifest -outputresource:test.exe;1

该命令的作用是将test.intermediate.manifest清单文件嵌入到test.exe可执行文件中。这时test.exe可以正常运行。打开vs2005的集成开发环境,从菜单打开test.exe,可以看到一个树形结构,双击“RT_MANIFEST”的子选项可以看到其内容与test.intermediate.manifest中的一模一样,所以依赖的VC运行时库的版本都是8.0.50608.0。于是问题就出来了,我的系统中根本没有8.0.50608.0版本,为什么test.exe仍可以正常运行呢?

Dependency Walker打开test.exe可以看到其所依赖的运行时库为“c:/windows/winsxs/x86_microsoft.vc80.crt_1fc8b3b9a1e18e3b_8.0.50727.4053_x-ww_e6967989/MSVCP80.DLL”,该运行时库的版本为8.0.50727.4053。在微软MSDN网站的一篇文章“Side-by-side Assemblies”中找到这样一句话:“If there is no relevant manifest, the system loads the default version of the assembly”,也就是说当系统中没有指定的VC运行时库时,系统会使用默认的VC运行时库。在MSDN的另外一篇文章“Assembly Versions”中还有一句话“Each assembly version is associated with a version number having four parts separated by periods: major.minor.build.revision….. A version number that changes only in the build or revision parts indicates that the assembly is backward compatible with prior versions.”,也就是说当只有运行时库版本号的后面两部分改变时,该版本是向后兼容的。

从上面的分析中可以推断出以下两点

  1. test.exe运行时首先在系统中搜索版本为8.0.50608.0VC运行时库,当没有搜索到所依赖的版本时,系统会调用默认的版本8.0.50727.4053
  2. 版本为8.0.50727.4053VC运行时库对老版本8.0.50608.0向后兼容,所以test.exe完全可以正常运行。

那么系统为什么会选择8.0.50727.4053作为默认的版本呢,系统中还有一个版本8.0.50727.42存在?我们推断系统会在兼容范围内选择版本高的库作为默认的版本。这一点可以在路径“C:/WINDOWS/WinSxS/Policies”中找到答案。在该路径下找到VC80.CRT的文件夹,里面有两个后缀为“.Policy”的文件:8.0.50727.42.policy8.0.50727.4053.Policy,用文本工具分别打开:

8.0.50727.42.policy的中有一句关键的:

<bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.42"/>

可以看到CRT8.0.50727.42对版本号在8.0.41204.256-8.0.50608.0范围内的运行时库兼容。

8.0.50727.4053.policy的中关键的有两句:

<bindingRedirect oldVersion="8.0.41204.256-8.0.50608.0" newVersion="8.0.50727.4053"/>

<bindingRedirect oldVersion="8.0.50727.42-8.0.50727.4053" newVersion="8.0.50727.4053"/>

可以看到CRT8.0.50727.4053对范围在8.0.41204.256-8.0.50608.0和范围在8.0.50727.42-8.0.50727.4053的版本都兼容,自然系统会选择CRT8.0.50727.4053作为系统默认的VC运行时库啦。

就写到这里吧,希望我的经历对大家有所帮助。

 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值