VS2008、VS2010中如何屏蔽讨厌的MSVCR*.dll的引用

VS系列工具作为目前微软主打的集成开发环境,在历经了近20多年的发展后,到如今已经可以说是Windows平台上各种IDE环境中的翘楚了。很多别的开发工具已经难望其项背了,如今VS2010也已经面市很长时间了,但是因为笔者囊中羞涩,无法升级硬件,所以也没有办法去进行那个180天的VS2010体验之旅了,实为憾事。当然这是别话,现在我主要使用的依然是VS2008,用它来开发我想要的东西。当然主要指使用其中的VC++部分了。

在用VS2005或VS2008的VC++开发产品时,经常遇到的一个问题就是最终编译出的可执行文件Exe、Dll、Ocx之类会需要MSVCR90.dll、MSVCR80.dll等C库函数运行时Dll的支持,在一些较老的系统,如XP中,经常不具备这些新版本的运行库,导致产品发布推广成为一个严重的问题。在2008年我还在开发一款网游时,也遇到了同样的问题,虽然想尽了办法,也无法屏蔽对这个动态库的引用,不得已,客户端就又返回老的VS2003环境中进行编译开发,最终发布。

本着刨根问底的精神,我仔细琢磨了一下这个问题,貌似可以通过与最终产品一起发布Microsoft Visual C++ 2005/2008 Redistributable Package库来解决这个问题,但是这个库的个头有可能是你最终产品的n倍(n>=5),这就像买了一部手机,却给你了一座核电站来支持,最终用户是否能接受是个很纠结的问题。

再后来,我发现可以使用VS2008自带的安装程序制作工具,生成一个最简的VC++ Redistributable 包,体积也很小,但是一样需要一个额外的安装包来支持你的最终产品,很多产品经理是不太喜欢这种形式的,所以此问题还是很纠结。

在一次与一位网友讨论这个问题时,他兴奋的告诉我,他的总监解决了这个问题,方法就是修改一下编译选项,将/MD选项改为/MT选项,最终的可执行文件就不会包含对那些VC运行时DLL的引用了,可以很方便的发布和部署。真是个非常棒的消息,让一个纠结了我两年多的问题得到了彻底解决。首先让我们来看下这个云遮雾罩的编译开关究竟是干什么的?MSDN中的描述如下:

/MD

 使应用程序使用运行时库的多线程并特定于 DLL 的版本。定义 _MT 和 _DLL,并使编译器将库名 MSVCRT.lib 放入 .obj 文件中。

用此选项编译的应用程序静态链接到 MSVCRT.lib。该库提供允许链接器解析外部引用的代码层。实际工作代码包含在 MSVCR90.DLL, 中,该库必须在运行时对于与 MSVCRT.lib 链接的应用程序可用。

当 /MD 与 _STATIC_CPPLIB 预处理器定义 (/D_STATIC_CPPLIB) 一起使用时,您的应用程序将与静态多线程标准 C++ 库 (libcpmt.lib) 而非动态版本 (msvcprt.lib) 链接,但仍通过 msvcrt.lib 动态链接到主 CRT。

请注意,不支持 _STATIC_CPPLIB 预处理器定义和 /clr 或 /clr:pure 编译器选项的组合。有关 /clr 选项的限制的更多信息,请参见 /clr 限制。

/MDd

 定义 _DEBUG、_MT 和 _DLL,并使应用程序使用运行时库的调试多线程并特定于 DLL 的版本。它还使编译器将库名 MSVCRTD.lib 放入 .obj 文件中。

/MT

 使应用程序使用运行时库的多线程静态版本。定义 _MT 并使编译器将库名 LIBCMT.lib 放入 .obj 文件中,以便链接器使用 LIBCMT.lib 解析外部符号。

/MTd

 定义 _DEBUG 和 _MT。此选项还使编译器将库名 LIBCMTD.lib 放入 .obj 文件中,以便链接器使用 LIBCMTD.lib 解析外部符号。

/LD

 创建 DLL。

将 /DLL 选项传递到链接器。链接器查找 DllMain 函数,但并不需要该函数。如果没有编写 DllMain 函数,链接器将插入返回 TRUE 的 DllMain 函数。

链接 DLL 启动代码。

如果命令行上未指定导出 (.exp) 文件,则创建导入库 (.lib);将导入库链接到调用您的 DLL 的应用程序。

将 /Fe(命名 EXE 文件) 解释为命名 DLL 而不是 .exe 文件;默认程序名成为基名称.dll 而不是基名称.exe。

除非显式指定 /MD,否则将暗指 /MT。

/LDd

 创建调试 DLL。定义 _MT 和 _DEBUG。

 

看到这里,我恍然大悟,原来这个开关就是控制这个C运行时库的引用方式的,真是踏破铁鞋无觅处得来全不费工夫。

当然到这里先别忙着去修改你的项目属性中关于这个开关的选项,因为当你的项目也是一个LIB时,如果使用了/MT或/MTd选项时,最终的静态LIB中就会出现LIBCMT.lib中的大量符号,导致在别的项目引用你的这个静态LIB时出现重复定义符号而无法链接的错误,怎么解决呢?其实继续看MSDN中的帮助就可以得到答案:

传递给链接器的给定调用的所有模块都必须使用相同的运行时库编译器选项(/MD、/MT、/LD)进行编译。

呵呵,原来如此,所有的模块保持一致就完了,但是静态的LIB貌似还是无法引用,问题依旧怎么办呢?

那就是在引用了你自己的使用/MT或/MTd选项编译生成的静态LIB的项目中,不但指定对应的/MT或/MTd选项,而且需要忽略LIBCMT.lib库即可。

到这里这个很纠结的问题,总算是有一个非常完满的解决方法了。总结下来,其实也怪自己,《VC++语言参考手册》中其实早就描述过这个问题了,而我没有注意,导致为这个非常基础的问题纠结了这么长的时间,实在是汗颜。在这里也非常感谢那位总监高手,轻松的解决了这个问题。也为以后大家也不再为这个问题发愁,所以写成这篇文章,让大家作为参考。

总之,很多很纠结的问题归根结底其实就是基础问题,所谓不积跬步无以至千里,看来我还是要去再读一遍《VC++语言参考手册》了。

### 回答1: msvcr120.dllmsvcr140.dll是两个系统动态链接库文件,都是Microsoft Visual C++ Redistributable Package的一部分。 msvcr120.dll是Visual C++ 2013的运行库,它包含了Visual Studio 2013的所有C++类库。它的主要作用是为多个不同的应用程序提供支持,这些应用程序可能使用了Visual Studio 2013创建的C++应用程序。msvcr120.dll通常会随着这些应用程序一起安装,因此用户无需手动下载或安装。 而msvcr140.dll则是Visual C++ 2015的运行库,它跟msvcr120.dll的功能基本相同,主要是为Visual Studio 2015 创建的C++应用程序提供支持。通常情况下,只有安装了Visual Studio 2015的电脑上才能找到这个文件。 总的来说,msvcr120.dllmsvcr140.dll的区别主要在于它们所支持的Visual Studio版本不同。如果你需要在电脑上运行使用Visual Studio 2013创建的C++应用程序,那么你需要安装msvcr120.dll;如果你需要运行使用Visual Studio 2015创建的C++应用程序,那么你需要安装msvcr140.dll。当然,一些应用程序可能同时需要这两个dll文件才能正常运行。 ### 回答2: msvcr120.dllmsvcr140.dll都是Windows操作系统常见的DLL动态链接库文件,主要用于支持软件程序的运行和操作。它们的区别在于: 1. 版本号不同: msvcr120.dll的版本号是12.0.x.x,而msvcr140.dll的版本号是14.0.x.x。 2. 针对不同的操作系统:msvcr120.dll主要是针对Windows 7和Windows 8系统,而msvcr140.dll针对Windows 10系统和一些新版的微软开发工具。 3. 发布时间不同:msvcr120.dll是在2013年发布,而msvcr140.dll则是在2015年发布。 4.功能不同:msvcr120.dll主要用于支持Visual Studio 2013版本的软件程序,而msvcr140.dll主要用于支持Visual Studio 2015版本的软件程序。此外,msvcr140.dll更加稳定,运行效率更高,支持C++14和C++17标准的函数库。 总之,msvcr120.dllmsvcr140.dll的区别主要在版本号、功能支持、适用系统等方面。在使用软件时,需要根据所使用的开发工具、操作系统来选择正确的DLL文件,以确保程序正常运行和运行效率的提高。 ### 回答3: msvcr120.dllmsvcr140.dll是微软的运行库文件,用于支持应用程序运行。它们在不同版本的Visual Studio被使用。其msvcr120.dll是Visual Studio 2013的运行库文件,而msvcr140.dll则是Visual Studio 2015和2017的运行库文件。 虽然这两个文件都是为了支持程序运行而创建的,但它们在某些方面还是有所差异。msvcr120.dllmsvcr140.dll在功能上是基本相同的,都提供了诸如文件读写、内存分配、处理异常等功能。但由于它们分属于不同的Visual Studio版本,所以在具体实现和支持功能的程度上可能有所不同。 此外,对于使用不同应用程序的用户来说,他们可能需要同时安装多个版本的microsfot运行库文件,以确保他们的计算机可以支持各种应用程序运行。对于程序开发人员来说,了解不同版本的msvcr dll是很重要的,因为不同版本的运行库文件可能会影响程序的编译和调试。 总的来说,虽然msvcr120.dllmsvcr140.dll都是微软的运行库文件,但它们在版本、功能和支持程度上存在一定差异。无论是开发人员还是普通用户,都应该了解它们的具体特点,以便更好地使用和安装缺失的运行库文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值