[原创+分享]使用VS2010来进行MFC4.2的开发

BoweirrKing 2014-04-25 02:06:43
加精
此文尤其推荐那些对VC6.0有着无比怀旧情节的人来看:)

首先来简单对比一下两套系统:
VS2010,自带10.0版本的MFC、CRT等DLL库,新的编译器(部分支持C++ 11标准、包括LAMBDA表达式),功能强大而完善的IDE环境。新的安全特性与SHE处理函数。
VC6.0,自带4.2版本的MFC、CRT等DLL库,很老的编译器(并且很不标准),功能勉强够用的IDE环境。

VS2010生成的东西体积小、效率高,但是需要使用的基础支持库众多。为了发布一个几十k的小程序,还要一并发布msvcr100.dll msvcp100.dll MFC100.dll等等支持库。到目前为止这些库并不是随着操作系统一起发布的。

VC6.0生成的东西优化与安全性有限。但是一大优势是,它生成的程序,所需的基础支持库,如MFC42.dll ,msvcrt.dll,msvcp60.dll,从Windows XP时代就已经是随着操作系统捆绑发布的。这对于一个中小型程序的发布来说,无异是非常便利的。

那么,有没有一种办法可以将两者的优势结合起来呢?

答案是肯定的!下面且听我慢慢道来。(以下步骤和过程都是本人亲自试验成功的)

有了以上这个想法之后,基于“VS2010是向前兼容的”这样一个大前提,我做了大胆的设想与尝试。

首先用VC6.0建立了一个标准的MFC对话框程序。
然后用VS2010打开刚才建立的这个工程(吧DSW文件拖放进VS2010),将工程转换为VS2010格式的vcxproj
接下来,打开“项目”菜单->“xxx项目属性”->“配置属性”->“VC++目录”,进行如下设置:
可执行文件目录:$(ExecutablePath)
包含目录:e:\PlatformSDK\Include;
e:\PlatformSDK\Include\mfc;
e:\PlatformSDK\Include\atl;
e:\PlatformSDK\Include\crt
引用目录:留空
库目录:e:\PlatformSDK\Lib;e:\PlatformSDK\Lib\MfcLib_x86
源目录:留空
排除目录:留空
请重点注意,以上用的PlatformSDK使用的是Windows2003 platform sdk(官方下载地址),并且假设Platform SDK安装在e:\PlatformSDK
库目录Lib\MfcLib_x86的内容是从VC6.0的目录“VC98\MFC\Lib”复制出来的MFC4.2的所有lib文件,以及从 “VC98\MFC\Lib”复制出来的MSVCRTD.lib MSVCRT.lib MSVCPRT.lib MSVCPRTD.lib

这样设置完之后,就可以编译了。通常编译都不会有问题。链接是一定会失败的。基本上类似以下一些符号链接错误:
error LNK2001:无法解析的外部符号 ___security_cookie
error LNK2001: 无法解析的外部符号 ___report_gsfailure
error LNK2001: 无法解析的外部符号 __except_handler4
error LNK2001: 无法解析的外部符号 __NLG_Notify
error LNK2001: 无法解析的外部符号 __NLG_Destination
error LNK2019: 无法解析的外部符号 @__security_check_cookie@4


难道到这里就放弃了??

那一定是不会的了。

仔细分析一下,就可以知道,完全相同的代码,完全相同的MFC和CRT的lib库,无法通过编译,就是因为:编译器在编译过程中,自动的为你的代码添加了一些具有不同功能的语句。在这些新添加的语句中,引用到了上述这些外部变量或者函数。

这是新的编译器的特性,这是我们无法去改变的。所以只能从另外一个方向来解决此问题:从VS2010自带的MFC库里面,找到并分离出来以上这些符号和内容。因为VS2010自己是能够完全正常编译、并链接成功的。

经过粗略定位,以上缺少的符号,全部是位于msvcr100.lib里面的。所以只要在其中找到我们所需要的符号,将其分离出来,并链接到我们自己的工程中即可。

具体繁琐的分析和尝试过程暂且不表,用排除法剪除不必要的模块间的各种依赖之后,将需要的模块文件(OBJ文件)添加到工程中,再次编译、链接,大功告成!

成果验证:
使用VS2010或VS2013,配合Windows2003 Platform SDK + 上述之VC6的各种MFC库文件,再加上附件中提供的crtnew.lib,进行编译连接。
用Depends实用程序,查看VS2010编译出来的EXE(用MFC共享DLL模式编译和构建),如果看到只引用了MFC42.dll和msvcrt.dll,而没有MFC100.dll和msvcr100.dll,则说明成功。如下图:


在这个过程中,用到的工具就是VS2010自带的Lib工具。基本操作步骤就是用Lib工具导出所有的msvcr100.lib里面的obj文件,一个一个的试。

我已经把所有需要的obj文件,打包整合为一个lib文件了。大家可以直接下载并使用。
使用时,仅添加以下两行代码即可:
#include "crtnew.h"
#pragma comment(lib,"crtnew.lib")

附带我最终的成果: 把上面的图片保存到本地。重命名为.zip文件,用Winrar即可打开并解压。

也许看到最后,各位在想,这样折腾有什么实际意义?
我只能说:
1、我喜欢VC6.0+MFC4.2这样的开发组合,但是VC6.0的IDE现在用起来真的是过于简陋了。用2013岂不是很爽?
2、MFC4.2生成的程序的依赖库是捆绑在操作系统里面的,这一优势在长期之内还是会继续保持。
3、可以在MFC4.2的基础上,使用新的C++语言特性。告诉你,可以直接使用Lambda表达式,你会心动吗?
4、新奇、好玩。。。。。。
...全文
3227 30 打赏 收藏 转发到动态 举报
写回复
用AI写文章
30 条回复
切换为时间正序
请发表友善的回复…
发表回复
用户 昵称 2014-12-22
  • 打赏
  • 举报
回复
准备用新的编译器玩玩了,至于带不带库,那只要带上库就能用,就没什么不方便的。
likfeng 2014-12-19
  • 打赏
  • 举报
回复
Windows下安装软件多了MFC库多了也很正常,.net那才叫恐怖!
「已注销」 2014-05-21
  • 打赏
  • 举报
回复
那你现在还能找到这个封装WebBrowser的类吗?
BoweirrKing 2014-05-21
  • 打赏
  • 举报
回复
引用 25 楼 stsdfsd 的回复:
BoweirrKing你好,你在http://bbs.csdn.net/topics/80101234中提到CWebBrowser2内存释放不掉的问题,后来你说“问题已基本解决,各方面指标均已达到我比较满意的程度了”。我现在也遇到了同样的问题,CWebBrowser2占用的内存一直无法释放,反而增长得越来越多,我也用了一些自己能想到的办法尝试去解决这个问题,但是都没有效果。能分享一下你的解决方案吗?
CHTMLView是没有内存问题的,而直接使用WebBrowser2却有内存问题,所以我就以CHTMLView为模板,做了一个基于CWnd来封装WebBrowser的类。效果貌似还是可以的。
「已注销」 2014-05-20
  • 打赏
  • 举报
回复
BoweirrKing你好,你在http://bbs.csdn.net/topics/80101234中提到CWebBrowser2内存释放不掉的问题,后来你说“问题已基本解决,各方面指标均已达到我比较满意的程度了”。我现在也遇到了同样的问题,CWebBrowser2占用的内存一直无法释放,反而增长得越来越多,我也用了一些自己能想到的办法尝试去解决这个问题,但是都没有效果。能分享一下你的解决方案吗?
caojun19790629 2014-05-19
  • 打赏
  • 举报
回复
厉害无比 老师
dibotiger 2014-05-19
  • 打赏
  • 举报
回复
最近新进了一台平板. 习惯性地看厂商默认的程序都装了什么. 结果在控制面板的程序->卸载程序里, 我看到了VS2008 VS2010 VS2012 VS2013 4个发行包安装. 看到这一幕, 我更加深深地怀念了VC6了. 如果写几个驱动也要这么多发行包来支持, 那更是悲剧中的悲剧.
j805 2014-05-18
  • 打赏
  • 举报
回复
学习了。。。。。。。。。
BoweirrKing 2014-05-14
  • 打赏
  • 举报
回复
引用 17 楼 akirya 的回复:
[quote=引用 12 楼 BoweirrKing 的回复:] [quote=引用 8 楼 akirya 的回复:] C++很多特性是无法跨编译器的,这种做法无形的引入了多少隐藏的地雷啊。
这个问题我觉得应该不用担心,因为我相当于是用新编译器来编译旧的代码,而旧代码里面是没有用到任何新的C++特性的。 新的编译器更加标准和安全了而已。 并且,我补充进来的东西,也是从VS2010里面摘录出来的。 我目前在我自己的工程里面试验,一切正常。[/quote] 就算新编译器编译旧代码,但同样的东西不同版本的编译器是有差异的。 看看winsxs,在我机器里,VC8的运行库dll有7套。[/quote] VC8的运行库dll有7套这个是不假。但是VC6的运行库主要只分为两套,一套是x86的,一套是x64的。 刚才百度了一下,VC6下确实可以进行x64的编译,但是无法调试。 所以,对于你所说的这个问题,我可以提供以下的回答: 1、我的这个方法,是用于x86平台下的MFC42的开发、调试。 x64程序还是建议使用VS2005以上的版本。因为我没有找到MFC42.lib等库文件对应的x64版本。 2、目前来讲,你所说的不同版本的编译器是有差异的,即x86平台下的种种差异(包括SEH差异、堆栈安全检查等),我已经通过主帖中的方法加以解决了。 若大家真的发现有问题(在VC6下可以正常编译运行但换了我的方法就不行),可以在这里留言或私信我,我会尽力解决的。
ojc520520 2014-05-14
  • 打赏
  • 举报
回复
学习了。。。。。。。。。。。
austin9972 2014-05-12
  • 打赏
  • 举报
回复
「已注销」 2014-05-12
  • 打赏
  • 举报
回复
机智,但是还是学习新的编译器吧,新的算是紧跟时代吧
  • 打赏
  • 举报
回复
引用 12 楼 BoweirrKing 的回复:
[quote=引用 8 楼 akirya 的回复:] C++很多特性是无法跨编译器的,这种做法无形的引入了多少隐藏的地雷啊。
这个问题我觉得应该不用担心,因为我相当于是用新编译器来编译旧的代码,而旧代码里面是没有用到任何新的C++特性的。 新的编译器更加标准和安全了而已。 并且,我补充进来的东西,也是从VS2010里面摘录出来的。 我目前在我自己的工程里面试验,一切正常。[/quote] 就算新编译器编译旧代码,但同样的东西不同版本的编译器是有差异的。 看看winsxs,在我机器里,VC8的运行库dll有7套。
nettman 2014-05-11
  • 打赏
  • 举报
回复
竞天问 2014-05-11
  • 打赏
  • 举报
回复
我只能说很牛X,但是我不会这样做,太危险
Nxp_icapply 2014-05-11
  • 打赏
  • 举报
回复
line_us 2014-05-10
  • 打赏
  • 举报
回复
这个法子挺好。
BoweirrKing 2014-05-10
  • 打赏
  • 举报
回复
引用 8 楼 akirya 的回复:
C++很多特性是无法跨编译器的,这种做法无形的引入了多少隐藏的地雷啊。
这个问题我觉得应该不用担心,因为我相当于是用新编译器来编译旧的代码,而旧代码里面是没有用到任何新的C++特性的。 新的编译器更加标准和安全了而已。 并且,我补充进来的东西,也是从VS2010里面摘录出来的。 我目前在我自己的工程里面试验,一切正常。
BoweirrKing 2014-05-10
  • 打赏
  • 举报
回复
引用 9 楼 TDXH2012 的回复:
VS2010生成的东西体积小、效率高,但是需要使用的基础支持库众多。为了发布一个几十k的小程序,还要一并发布msvcr100.dll msvcp100.dll MFC100.dll等等支持库。到目前为止这些库并不是随着操作系统一起发布的。 这个问题很简单,项目属性里面选择MFC静态链接就可以了,只要一个绿色EXE文件, 其他文件一概不要,相当好! 具体操作为:项目属性=》配置属性=》常规=》MFC的使用项,选择“在静态库中使用MFC”
这个是没错的,但是静态链接出来的东西,相比于VC6动态链接出来的程序,还是要大上不少啊!!
图灵转世 2014-05-10
  • 打赏
  • 举报
回复
对,静态编译mfc就可以了。
加载更多回复(9)

16,466

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧