社区应用 最新帖子 精华区 社区服务 会员列表 统计排行 银行

  • 7876阅读
  • 3回复

Vc2013实战

级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
我对软件业的趋势,这么理解: 主要市场在可预见的十年,仍然集中在web、ios、android、windows四个方向。这四个方向之外的东西,是浪费精力。很显然,目前并不存在某种开发模式,能够横跨这四个领域,别跟我说html5,话说甚至facebook,都已放弃Web客户端回到原生客户端。 快,仍然是、甚至永远必须面对的问题。


    windows桌面开发,目前而言,首先面临的是传统的桌面开发,还是基于winrt的windows应用开发。我的答案,是略关注win8应用开发,但传统的桌面开发在我们的职业生命中仍然是主流。在手机、平板等逐渐侵蚀PC使用时间的大背景下,Win8及后续技术,能够在未来五年中取得何种成果,很难预测。在移动领域开发中,微软的Win8我认为是暂时可以忽略的东西---只要其市场占有率上不来,大家根本无需浪费精力。  


    基于上面的判断,所有号称跨平台的Gui库,我毫不在意。为什么,Linux和mac没有任何意义,我们无需付出如此重大的代价。而wince、windows obile、linux移动领域的开发,已经正式死亡。在嵌入式领域,android很明显将渐渐的让单纯的linux系统消失。


     就目前为止,Windows原生桌面应用,C++仍然是重要的选择。 就Gui的选择而言,大致上包括如下几类:


   1、Mfc和Wtl:仅使用windows


   2、Qt和wxWidget:可运行于windows、linux、mac


   3、direct ui:金山、迅雷提供了相应的方案,也有一些开源项目。


   4、其它小众平台:一些开源的Gui项目,但是,由少数人来完成庞大的工程,靠谱程度有限。


    根据上述趋势的判断,Qt和wxWidgets可以放弃,direct ui尚没有真正取得市场优势的产品,小众的平台几乎无需考虑。 剩下的尽在wtl和Mfc之间选择...如果你知道,wtl在最近四年,几乎陷入休眠的话,我想,大家仍然只剩下唯一的选择:MFC。


    因此,就windows桌面开发而言,我相信Mfc仍然是唯一的选择。很多原生开发人员一直渴望,希望将Xaml用于原生开发领域。这个愿望在技术上是完全可行的,WinRT开发,Xaml和C++能够很好的结合,但...只能运行在Win8+。   微软连续十多年拒绝原生开发人员的渴望,相信是出于其商业策略。 而在今后的五年中,相信企业多数计算机,不会升级到Win8。那么,在这段时间,老老实实的使用Mfc,不用奢望其他。


   结论很简单:Windows桌面应用,C++是重要的选择。Gui选择Mfc最优且中规中矩。Ide很明显是Visual Studio,最新的版本是vs2013。当然,实际上VC的资料绝大多数是基于VC6的,vc2010以后的极少,接下来,我会逐步的介绍Vc2013的一些常识。前后产生的代码,在https://github.com/by90/Stock 的develop分支。我们大致会接触以下的问题:


   1、创建项目


   2、使用Git


   3、使用Dll组织项目


   4、原生单元测试


    5、Sdi切换CFormView视图


    6、调用Dll中的Doc/View


    7、插件模式


    8、使用sqlite
关键词: c++ 编程
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 沙发  发表于: 2014-08-02
彻底厘清C运行库的涵义
一、什么叫C运行库:
1、由来:
   C运行库,即C Runtime library,简称CRT。
   C语言是小内核语言,其本身只处理少量的关键字、数据类型和基本流程控制。其内核开发出来后,C语言重写了Unix的90%的系统函数,并提取最常用的部分,形成了头文件和Lib库,C运行库产生。换言之,此时使用C语言本身和C运行库,在Unix下开发。
   运行库包括C程序运行的最基本的函数,规模几近数千个函数。比如通过main开始运行,exit退出,printf之类的函数、错误处理等。换言之,没有运行库std,C程序根本不能运行。
2、Ansi C标准和 Standard Library
   C逐渐流行,不同的编译厂商,在不同的平台上实现了Standard Library,当然都是平台相关的,这对于程序员而言显然带来紊乱。于是有了Ansi C标准,该标准除了详细定义C语言各要素的具体含义外, 同时规定了Standard Library的标准。因此Std由各编译厂商根据Ansi标准提供。
3、C++的标准库:
   C++的Standard C++ Library,包括上面的C 运行库和Stl,显然,由于C++是C的超级,C运行库被简单的加入,没有必要另写一套。


二、VC++里的C运行库
在vs2013中,同一解决方案,每个项目应使用相同的C运行库。我们在解决方案资源管理器中,选中项目|右键|属性,打开该项目的属性页:配置属性|C/C++|代码生成,可以选择"运行库",有四个选择:多线程(/MT),多线程调试(/MTD),多线程Dll(/MD),多线程Dll调试(/MDD)。这四个选择,MT和MD是release版本,MTD和MDD是Debug版本,所以我们只要弄清MT和MD的区别。  /MT 即multithread, static version,多线程静态版本。这种方式下,编译器静态的链接LIBCMT.lib。/MD是multithread- and DLL-specific version,多线程DLL版本。这种方式下,编译器链接MSVCRT.lib,而动态的使用MSVCRT*.dll。它们的区别是:
1、静态运行时,使用LIBCMT.lib。动态运行时使用MSVCRT.lib+MSVCRT*.dll。
2、使用静态运行库,CRT会链接进EXE文件,生成的EXE文件大些,但运行时不用加载CRT。使用动态运行库,编译的EXE文件小些,但程序启动后需要Load CRT,加载MSVCRT*.dll文件,性能略低。


三、VC中C运行库设定的铁律:
1、同一解决方案,各项目使用相同的运行库设置,否则不仅可能无法生成,即使通过编译,也会带来多种潜在隐患
2、使用第三方库,必须编译和项目设置相同的版本,如果不能,则只能弃用。3、如果使用动态运行时/MD或/MDD,则MFC应用程序,只能选择在共享Dll中使用MFC,不能静态链接MFC。反过来说,如果MFC要静态链接到Exe文件,则必须使用/MT或/MTD




四、常见的编译错误:


当解决方案不同项目的运行库设置不同的时候,首先会出现一堆类似如下的错误:
MSVCRTD.lib(MSVCR120D.dll) : error LNK2005: _memmove 已经在 libcmtd.lib(memmove.obj) 中定义
然后:
LINK : warning LNK4098: 默认库“MSVCRTD”与其他库的使用冲突;请使用 /NODEFAULTLIB:library
fatal error LNK1169: 找到一个或多个多重定义的符号


原因很简单,Mfc应用和Dll项目之间,在链接另一个项目的类似lib、obj时,很明显,由于运行库设置不同,编译器面对两个运行库,选择链接哪一个运行库的函数,显然是很困难的事情,只好简单的告诉你:编译失败。将两者的运行库设置改为一致...无论哪一个,一致就好,问题解决。一些文章提到的另外两种解决方式:1、人为的忽略一个库;2、强制编译,都是有隐患的,某种意义上来说,是误导。请遵循上面提到的铁律:同一解决方案中,所有项目使用相同的运行库设置。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 板凳  发表于: 2014-08-02
创建原生C++单元测试项目
一、创建测试项目
    在解决方案资源管理器,选中解决方案。
    右键|添加|新建项目,进入"添加新项目"对话框。
    依次选择Visual C++|测试|本机单元测试项目
    我们创建一个名为TestStock的单元测试项目,当然,仍然将显示方式改为:显示全部文件。

二、运行测试:
在主菜单,选择测试|窗口|测试资源管理器。运行全部测试:测试项目会编译,由此测试资源管理器将发现向导产生的名为Test1的测试,当然,这个会通过。

三、能够测试Mfc项目中的类吗?
    多数文章介绍的是针对Dll项目的测试。我们能否测试Mfc应用项目中的类呢?答案是可以,测试项目需要链接Mfc应用项目中的相应的obj文件。步骤如下:
1、在Stock项目中创建要测试的类
   我们创建一个名为Demo的类,这会增加对应的头文件和cpp文件。然后编译Stock项目
2、测试项目中设置附加依赖库目录、附加依赖项、包含目录
在测试项目的属性页中,配置属性|链接器|常规,然后再附加库目录中加入:
$(SolutionDir)Stock\$(Configuration)
这个使用了两个宏,当前的配置是Debug,那么$(SolutionDir)表示解决方案的目录,$(SolutionDir)Stock表示解决方案下的Stock目录,而$(Configuration)在debug配置中的值为Debug。这实际上是说明,如何找到demo.obj

然后在链接器|输入中,编辑附加依赖项,加入demo.obj,注意不要带路径,只是文件名,上一步骤已经列出了去哪个文件夹下寻找。

当然,要使用demo类,我们还需要#include "demo.h",因此我们要设置,在何处找到该头文件:在测试项目的属性页中,配置属性|C/C++|常规,编辑"附加包含目录",加入$(SolutionDir)Stock,这是Demo.h所在的文件夹。

3、在测试项目中创建Demo类的实例
我们简单的在向导生成的unittest1文件中
加入:#include "Demo.h"
然后在TEST_METHOD(TestMethod1)函数里,简单的创建实例
Demo demo;
然后编译测试项目,遇到了两个错误:C运行库问题和未链接预编译对象问题,现在知道上一篇文章的出处了吧?

4、C运行库的问题
   我们创建Mfc应用的时候,是采用静态链接Mfc的方式,因此,使用的是/MTD方式静态链接C运行库。单元测试项目,默认使用/MDD方式动态链接C运行库。
   将单元测试项目的运行库设置,修改为/MTD即可。
   在测试项目的属性页,配置属性|C/C++|代码生成:运行库设置修改为多线程调试 (/MTd)

5、未链接预编译对象问题
   这个,是由于demo.cpp中include了stdafx.h,预编译头文件。我们如同加入demo.obj一般,加入stdafx.obj即可。

四、我们实际写一个测试:
1、在Stock项目中的类视图,为demo类增加一个Add方法,做两个整数的加法
    头文件里增加了Add方法,Cpp文件也增加了,不过是返回0,没做任何事情。显然,我们还没有完成任务。
2、在单元测试中,测试加的结果对不对:
TEST_METHOD(TestMethod1)
{
Demo demo;
Assert::AreEqual(5, demo.Add(2, 3));
}
3、运行测试:失败,那是当然
    期待5,但是返回0
4、我们回头来,实现Add方法:
int Demo::Add(int a, int b)
{
return a+b;
}
5、再次运行测试,通过。

按照TDD的思维:先写测试,再以最简单的方式通过测试,不过在IDE中无需这么教条,我们可以先创建类,通过类视图创建方法,然后再先测试、实现方法、第二个测试、通过第二个测试...很明显,一定要体验编译不通过的滋味,过于变态。


五、直接测试CStockApp类
    注意,测试项目中,MFC的使用,默认设置为是"使用标准windows32库",不需要修改它。按照如下步骤,我们可以创建一个CStockApp的实例,并测试其函数:
1、在测试文件中,#include "Stock.h"
    此时编译不通过,我们需要在#include "Stock.h"前加入:
    #include "..\Stock\stdafx.h",话说Stock项目和测试项目的预编译头文件,都要include,当然,测试项目的要放在第一行
2、在附加依赖项中,加入Stock.obj
   编译仍然不能通过
  因为Stock.cpp依赖其它三个obj文件,我们逐一加入,最后如下:
stdafx.obj
demo.obj
StockDoc.obj
StockView.obj
MainFrm.obj

3、在TEST_METHOD(TestMethod1)函数中创建CStockApp的实例并执行一个函数
CStockApp app;
int i = app.GetDataVersion();
Assert::AreEqual(-1, i);

4、运行测试:出乎意料的通过。这里只是看看,能否在单元测试中使用MFC对象。
       vs2013中原生单元测试,Msdn相关资料链接如下:http://msdn.microsoft.com/en-us/library/hh598953.aspx
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
级别: 管理员
发帖
8532
金币
2762
威望
3231
贡献值
0
元宝
0
只看该作者 地板  发表于: 2014-08-02
使用Git和Github
一、使用Git
Vs2013内置了Git SourceProvider,因此,可以简单的在本地使用Git管理源代码。
步骤是:
1、使用Git提供程序:
    主菜单上,工具|选项|源代码管理,当前源代码管理插件,选择microsoft git提供程序。
2、在解决方案资源管理器,选中解决方案,右键,加入到源代码管理。
ok,现在可以提交(实际上是解决方案目录下的.git目录)、撤销、管理分支,基本上不用命令行,就可以正常的使用Git管理源代码。


二、发布到Github
这里要用到Github的工具,即Github For Windows
安装之后,使用Github的用户名和密码登录Github成功,然后:
1、在github上创建一个空的Stock的库
2、在本地,执行github for windows,在local中增加Stock
3、双击本地的Stock
   在repository setting中,将remote repostory设置为:
   https://github.com/by90/Stock.git
  可以看到,本地的Stock和远程的Stock已经联系起来
4、然后再local中,publish,这样建立关联,以后可以使用同步了
此后,就不再需要Github For windows,在vs2013中,就可以使用同步、push、pull等操作,将本地库的变更,推送到Github。


经测试,发现Github For Windows存在问题:本地使用unicode的情形下,提交时会自动更改编码。
改用命令关联远程库:
git remote add origin https://github.com/by90/远程库的地址.git



三、Git的分支和流程约定:
1、使用develop分支保留最新工作进度:
我们创建分支develop,并在该分支上执行"发布分支",在Github上创建并关联远程的develop分支。这是用来保存最新进度的。
2、使用本地临时分支工作:
      我们要做任意一项工作,就从develop创建一个新的临时分支,做完了再合并到develop并删除临时分支,然后将develop推送push到github。永远不要直接在develop分支和master分支工作。临时分支,修复Bug以Fix开头命名,发布版本以release开头命名,其他命名方式都是临时开发分支。
3、使用master分支保留每个发布版本:
当develop可以发布一个小版本的时候,我们同样创建新的临时分支,让发布版本相应工作做好,然后合并到develop,然后合并到本地的master,将master推送到github
换言之,master用来保存一个个的小版本。

4、Github上只有master和develop两个分支:
      本地的两个分支分别与Github上的同名分支关联。
QQ: 378890364 微信:wwtree(省短信费) 紧急事宜发短信到0061432027638  本站微博:http://t.qq.com/wwtree QQ群:122538123
描述
快速回复

您目前还是游客,请 登录注册
如果您在写长篇帖子又不马上发表,建议存为草稿