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++语言参考手册》了。

转载于:https://www.cnblogs.com/java0721/archive/2012/05/31/2602986.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/297013.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

听说,99%的数学家都算不出这道题

全世界只有3.14 % 的人关注了爆炸吧知识著名的数学家毕达哥拉斯曾说:“朋友是你灵魂的倩影,要像220与284一样亲密。”就因为不经意的一句话,引发了一场数群和数学家长达几千年的“斗争”,甚至到现在依然没有结束!无数个…

oracle账号区分大小写吗,实战Oracle 11g用户密码不区分大小写

连接到:Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - ProductionWith the Partitioning, OLAP, Data Mining and Real Application Testing optionsSQL> show  parameter sec_case_sensitive_logonNAME TYPE VAL…

sql 多表多行模糊查询_从零开始学习SQL(五)多表查询

经过之前的学习,现在我们已经对查询有了一定的了解,但是我们目前的所有查询都只能找到在一张表中的数据,但如果我们需要寻找分布在多张表格中的数据时,这种之前的查询就做不到了,这时就需要引入一种新的查询方法&#…

最新.NET MAUI有什么惊喜?

点击蓝字关注我们.NET 6 RC1 现已发布啦,我们为 .NET 多平台应用程序 UI (MAUI) 引入了所有的新布局。这是性能和可靠性的重大变化。我们很高兴我们还增加了一些关于accessibility方面的基于新的SemanticService、字体缩放选项和对Xamarin.Forms 效果的兼容性的功能…

onWindowFocusChanged

这个onWindowFocusChanged指的是这个Activity得到或者失去焦点的时候 就会call。 也就是说 如果你想要做一个Activity一加载完毕,就触发什么的话 完全可以用这个!!! package com.app.android05; import android.app.Activity; imp…

亲一下就搞定的事,绝不花钱解决!

1 好了,你表演吧,球不看了2 “你这个车,至少得100条小鱼干啊” 3 羡慕了4 还…还有这种操作?5 被秀了一脸哈哈哈6 没有什么是一个么么哒解决不了的!你点的每个赞,我都认真当成了喜欢

SetComputerName改网络中计算机名

通过 Wiz 发布转载于:https://www.cnblogs.com/xe2011/archive/2012/06/02/2531620.html

VS2010自定义新建文件模版

不知不觉VS2010已经成为.NET开发人员的必备工具,相比经典版VS2005,到过渡版VS2008,2010在性能稳定性和易用性上都得到很大的提高。 结合VS工具,其下的插件也层出不穷。今天重点给大家介绍如何使用VS2010VS2010自定义新建文件模版&…

微软发布了Visual Studio 2022 RC版,并将在11月8日发布正式版

微软今天发布了Visual Studio 2022 最接近正式发布的RC版本,同时宣布在11月8日发布正式版,届时将在线上发布虚拟的发布活动,具体参见:https://devblogs.microsoft.com/visualstudio/join-us-november-8th-for-the-launch-of-visua…

python装备_Python重型武器:Django

Django,发音为[dʒŋɡəʊ](詹戈) ,是用python语言写的开源web开发框架,并遵循MVC设计。MVC框架的核心思想是:解耦,让不同的代码块之间降低耦合,增强代码的可扩展性和可移植性,实现向后兼容。M…

安卓 广告位

需求:类似网易新闻客户端,listview头部要显示广告位,广告位数量动态从后台获取,并且不一定一直有广告位 问题:listview下拉刷新与广告位touch事件的冲突解决,广告位的左滑右滑事件与整个fragment的左右切换…

arcgis oracle trace,ArcGIS应用Oracle Spatial特征分析

该文章并不是将Oracle Spatial与ST_Geometry做对比,关于两者的对比,可以参考:http://www.linuxidc.com/Linux/2011-10/45492.htm,这里从数据结构,到性能对比,都描述的很清楚。其实这篇文件就是说明一下在A…

SharePoint Timer Job

首先介绍一下什么是定时器作业,说的再多,也不如一张图说的清楚这两张图应该把我想说的已经表达清楚了,下一步介绍一下如何自定义Timer Job第一步:创建一个类(CustomTimerJob.cs)第二步:引用 usi…

python获取div标签的id_Python 获取div标签中的文字实例

预备知识点compile 函数compile 函数用于编译正则表达式,生成一个正则表达式( Pattern )对象,供 match() 和 search() 这两个函数使用。语法格式为:re.compile(pattern[, flags]).compile(pattern[, flags])参数:pattern : 一个字…

生活是长跑

人生不是百米冲刺,是长跑,需要日积月累,建立自己的人生观,生活态度,从各个方面去不断的积累自己,最后才能获取成功的人生。 生活是一个系统工程,每一方面都要经营维护,不要因为某种…

这次使用一个最舒服的姿势插入HttpClient拦截器技能点

码甲哥继续在同程艺龙写一点大前端,今天我们来了解一下如何拦截axios请求/响应?这次我们举一反三,用一个最舒适的姿势插入这个技能点。本文阅读耗时5 minute,行文耗时5 Days。axios是一个基于 promise 的网络请求库,可…

甜蜜助攻!情侣之间,到底能有多甜甜甜甜甜甜甜甜

▲ 点击查看没有一丝丝防备,还有 5 天,七夕就要到了。如何借「物」聊表爱意,大概是最近让很多拥有另一半的人头疼不已的问题。重点是,礼物挑不好,小心七夕就变送命题!女孩子们到底喜欢什么礼物?…

套接口和I/O通信

几个I/O相关的函数&#xff1a; #include <unistd.h> ssize_t read(int fd, void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count); int close(int fd); 为了实现通信&#xff0c;fd可以是套接口&#xff08;见linux的套接口和管道&#xff…

oracle bcp out,SQL Server利用bcp命令把SQL语句结果生成文本文件

这篇文章主要为大家详细介绍了SQL Server利用bcp命令把SQL语句结果生成文本文件&#xff0c;具有一定的参考价值&#xff0c;可以用来参考一下。感兴趣的小伙伴&#xff0c;下面一起跟随512笔记的小编两巴掌来看看吧&#xff01;在SQL Server里可以调用DOS下的命令行工具bcp来实…

多个查询语句能否一次把结果导出_mysql表中base64格式数据查询

需求&#xff1a;为了避开特殊字符(如&#xff1a;单引号)影响&#xff0c;把某些字段保存为base64格式。SQL语句直接解码base64编码数据&#xff0c;直接查询出原始数据。表中数据如下很不直观&#xff0c;当根据where条件查询时&#xff0c;肉眼不能直接从结果提取到可读信息…