注册CSDN数年了,突然发现可用分有点多,上半年放了些200分的贴子,结果现在又涨回来了:(,于是决定趁现在时间略有余裕的时候再回报一下诸位道友:)
我会每天放一个200分的贴子,与大家讨论一些有意思的话题。CSDN充斥了太多没什么意思的技术的细枝末节,让人常常晕晕欲睡。根据我的可用分,不出意外的话,时间大概会坚持两个月左右。嗯,60个话题,足够了。
做软件最忌浮躁,一些基础概念的清楚明析对初学者往往带来莫大的收益,少走无数的弯路。可惜平常我们高谈MDA/STL/GP/J2EE/.net/UML/design pattern/...的时候,一些最基础的概念却常常在我们的言语中被模糊。国内的教育环境本不是太好,很多初学者只好在迷惑中前行。坦白说,当年我从每一次接触windows编程到真正明白什么叫“Win32编程”,中间花了很长的时间,是的,很长。相信这里很多人亦是不明白,为什么叫win32呢?为什么不是win31或者win95呢?好像没用过这样一个操作系统啊?呵呵,我也没有用过。
我在这里只是抛砖引玉,希望各位来把自己弄清楚了的一些常见IT术语解释一番,能深入浅出当然更妙,但千万不要长篇大论,那不适合论坛(兵贵精而不在多)。同时要写比较有把握的,而不是自己心中亦模棱两可的。我先随便写几个,以后想到了我再加。 "Win32编程”:my god,我一时还真拿不准为什么叫win32了,如有缺失请为我补充。微软操作系统在win31及其以前都是DOS系统,windows只是在dos下运行的一个大程序而已。在其后win95则稍有改变,windows除了DOS核心以外也真正成为了操作系统的一部分,提供着各类操作系统提供的服务。应该说,在win95之后的windows(longhorn以前,包括nt)都可以称之为win32系统平台。所以在这样的平台上,直接或间接使用系统提供的API编程,就称之为Win32编程。对Visual Studio而言,Win32编程一般包括SDK、MFC、ATL这几类,其中ATL在国内应用不是很广泛,一般应用于以COM组件为架构的中大型软件产品,单纯的软件项目中鲜有见到。
我会每天放一个200分的贴子,与大家讨论一些有意思的话题。CSDN充斥了太多没什么意思的技术的细枝末节,让人常常晕晕欲睡。根据我的可用分,不出意外的话,时间大概会坚持两个月左右。嗯,60个话题,足够了。
做软件最忌浮躁,一些基础概念的清楚明析对初学者往往带来莫大的收益,少走无数的弯路。可惜平常我们高谈MDA/STL/GP/J2EE/.net/UML/design pattern/...的时候,一些最基础的概念却常常在我们的言语中被模糊。国内的教育环境本不是太好,很多初学者只好在迷惑中前行。坦白说,当年我从每一次接触windows编程到真正明白什么叫“Win32编程”,中间花了很长的时间,是的,很长。相信这里很多人亦是不明白,为什么叫win32呢?为什么不是win31或者win95呢?好像没用过这样一个操作系统啊?呵呵,我也没有用过。
我在这里只是抛砖引玉,希望各位来把自己弄清楚了的一些常见IT术语解释一番,能深入浅出当然更妙,但千万不要长篇大论,那不适合论坛(兵贵精而不在多)。同时要写比较有把握的,而不是自己心中亦模棱两可的。我先随便写几个,以后想到了我再加。 "Win32编程”:my god,我一时还真拿不准为什么叫win32了,如有缺失请为我补充。微软操作系统在win31及其以前都是DOS系统,windows只是在dos下运行的一个大程序而已。在其后win95则稍有改变,windows除了DOS核心以外也真正成为了操作系统的一部分,提供着各类操作系统提供的服务。应该说,在win95之后的windows(longhorn以前,包括nt)都可以称之为win32系统平台。所以在这样的平台上,直接或间接使用系统提供的API编程,就称之为Win32编程。对Visual Studio而言,Win32编程一般包括SDK、MFC、ATL这几类,其中ATL在国内应用不是很广泛,一般应用于以COM组件为架构的中大型软件产品,单纯的软件项目中鲜有见到。
“MFC”:这个词在这里讨论好像有点班门弄斧的感觉:)还是说一下吧。Microsoft Framework class(不知道对不对,汗...),大家都知道,使用SDK编程往往有很多每次都要重复的固定不变的一些代码,为了提高编程的效率,减少上千个API带给开发人员巨大的精神压力,微软开发出了这么一个类库,注意,这个类库与操作系统本身无任何关系,它只是对API进行了一个面向对象的封装,当然,还给出了一系统编程采用的框架。使用SDK的方法,使用Visual Studio,通过调用API,MFC你也可以做得出来。MFC把一些固定不变的代码已经写好了,只在编译时候链上,所以我们的代码里看不到WinMain(),而事实上整个程序的运行,和SDK的方式无任何区别,初学者请记住这一点。另,补充一点个人感想,MFC的初衷,带给开发人员更多的便利,我觉得并不太成功。
“GDI”:Graphic Device Interface,这个是Win32程序下最常用的显示方式,与DirectX、OpenGL处于同一级。在DOS要显示一些东东可不是容易的事,最简单的是调用一些C的图形库函数来实现显示,不过一般也就是些画线,填色,输出几个文字,效果很弱(所以DOS程序界面一般都不怎么样),要复杂一点的动画/图片显示什么的,经常要用到的就是硬件中断,调用一些显卡子程序来做。因为每一个显卡都不同,所以DOS的游戏兼容常常由于显卡的差异而很糟糕。到Windows下大家就幸福多了,Windows将硬件这一层屏蔽起来,用一个表格(Device Context)来代表一个显示,我们要做的就是在这个表格上填好相关参数,然后画上我们想画的东东,然后操作系统会依照这个表格(DC),把相应的显示内容(一般是一块显示内存)传送到指定显卡的指定的显存,再由显卡传给显示屏。我们不再需要与不同的显卡打交通,这是一个十分伟大的胜利!GDI中最常用的是双缓存技术,也就是说你可以在内存中创建(也就是复制)一个DC,只不过在这个DC中显示的不再被传送到显示器上。有什么用呢?因为它的各参数是与当前屏幕DC一致的(COPY嘛 ,当然是这样),所以它的显示内容可以完整无失真地传送到屏幕DC上。我们通常在内存DC上画图,譬如画一圆,再画一条直线,画完后一次性地传送到屏幕DC上,这样对用户来说屏幕只刷新了一次,可以解决你画一点内容屏幕即刷新一次导致的闪烁问题。当然,双缓冲甚至多缓冲还有很多别的用处,那就要靠自己揣摩了。
MFC => Microsoft Foundation Classes
"COM”:component object model,组件对象模型,一般简称组件。这是微软为了解决代码重用的一个重要机制。重用代码的最简单办法是源代码重用,把写好的函数和类加到自己当前的代码中,编译即可。简单是简单,敝病却显然地多。另一个常用的方法是单独做成模块,以DLL的形式分发,DLL导出函数或者类,客户程序用动态/静态链接的方法将其加载,这显然比前一种源代码的重要好一些,难度也不大,最为常用。但DLL也有一些不足,最根本的,它不是二进制兼容,DLL版本升级一次就需要与客户程序代码重链接一次,有些时候这几乎是不可能的任务。为了更好地让编程像“搭积木”一样简单,让模块可以完美地配合,完美地替换,COM产生了。COM不是类库,不是代码,不是操作系统的服务,而是一套编程模型,理论上来说,它与语言无关,与操作系统无关,unix下同样可以做COM。COM是一种程序结构模型标准,你做的DLL或EXE在结构上满足这么一个标准,那这个DLL或EXE就是一个组件,它将在该平台上成为二进制兼容。COM主要利用了注册表来登记本模块的信息。客户程序调用时首先查注册表,找到所需组件的位置(这实现了位置透明),然后就用Loadlibrary把它加载进来,这和普通调用没有本质区别,区别在于由于组件特殊的实现方法使得整个过程中用户程序都不知道组件的位置,组件的类的实例化过程,如何销毁,不能直接访问组件的任何实现细节,用户只与组件的几个public接口打交道。这将实现真正的模块之间的独立。对用户程序而言,对于目标组件的认识,除了接口,一无所知。在接口不变的情况下,组件可任意替换而客户程序不作任何改动,无需编译,仅这一点,在中大型程序的模块集成的过程中就将节约相当多的时间。
有关VC开发数据库的几种连接方式比较!(转自天极网)
ODBC (Open DataBase Connectivity)
ODBC是客户应用程序访问关系数据库时提供的一个统一的接口,对于不同的数据库,ODBC提供了一套统一的API,使应用程序可以应用所提供的API来访问任何提供了ODBC驱动程序的数据库。而且,ODBC已经成为一种标准,所以,目前所有的关系数据库都提供了ODBC驱动程序,这使ODBC的应用非常广泛,基本上可用于所有的关系数据库。但由于ODBC只能用于关系数据库,使得利用ODBC很难访问对象数据库及其它非关系数据库。由于ODBC是一种底层的访问技术,因些,ODBC API可以使客户应用程序能够从底层设置和控制数据库,完成一些高层数据库技术无法完成的功能。
MFC ODBC(Microsoft Foundation Classes ODBC)
由于直接使用ODBC API编写应用程序要编制大量代码,在Visual C++中提供了MFC ODBC类,封装了ODBC API,这使得利用MFC来创建ODBC的应用程序非常简便。DAO (Data Access Object)
DAO提供了一种通过程序代码创建和操纵数据库的机制。多个DAO构成一个体系结构,在这个结构中,各个DAO对象协同工作。MFC DAO是微软提供的用于访问Microsoft Jet数据库文件(*.mdb)的强有力的数据库开发工具,它通过DAO的封装,向程序员提供了DAO丰富的操作数据库手段。OLE DB(Object Link and Embedding DataBase)
OLE DB是Visual C++开发数据库应用中提供的新技术,它基于COM接口。因此,OLE DB对所有的文件系统包括关系数据库和非关系数据库都提供了统一的接口。这些特性使得OLE DB技术比传统的数据库访问技术更加优越。与ODBC技术相似,OLE DB属于数据库访问技术中的底层接口。直接使用OLE DB来设计数据库应用程序需要大量的代码。在VC中提供了ATL模板,用于设计OLE DB数据应用程序和数据提供程序。ADO(ActiveX Data Object)
ADO技术是基于OLE DB的访问接口,它继承了OLE DB技术的优点,并且,ADO对OLE DB的接口作了封装,定义了ADO对象,使程序开发得到简化,ADO技术属于数据库访问的高层接口。目前在VC应用的比较多的是ODBC和ADO,而DAO在VB等开发工具中应用更多一些!个人认为ADO是比较好的!目前也最流行!
HOOK实际上就是这样一种技术,能够提供一种手段,使程序员能够改变某种事件发生时系统的默认的行为。而应用HOOK技术进行处理较多的就是消息。windows系统捕获一个消息之后会根据消息的类别对消息做不同的处理。如果是驱动程序提供的硬件消息,则放入由系统维护的一个系统消息队列里面,然后在系统内核的帮助下将消息放入某个线程的私有消息队列里面去;如果是其它消息则直接放入对应的线程私有的消息队列里去。每个消息对应一个msg类型的消息结构,用于表示该消息的id,解手者句柄以及传递的额外参数。每个能够响应消息的线程都会有一个消息循环,该循环不断的从其消息队列里面取出消息结构,并根据消息里面包含的接收者窗口句柄调用该窗口对应的窗口函数。这是windows系统对消息进行的默认的处理,而有时我们需要对一些消息进行特殊的处理,不按照系统的流程进行,必须在消息到达目的地消息队列之前截获该消息,加上我们自己的处理,然后根据需要决定是否将消息发往起其最终的目的地。这一个目的是通过系统hook来达到的。
嗯,码字实在太累了,看来一天一题肯定是不行的,我尽力而为吧,力争做到一周一题。
由于所有文字均是我即时构思即时成文即时发贴,必有很多疏漏,希望各位大侠为我佐正。 "STL":Standard Template Library,标准模板库,这是最早由Alexander Stepanov和Meng Lee(好像是华人的名字哦)完成,于1994年提交给ANSI/ISO 标准C++委员会并通过而成为标准C++的一部分。望文生义即可知这是一个代码库标准,不是语法标准。简单地说,STL是以C++中的模板语法为基础建立起来的一套包含基础数据结构和算法的代码库。STL的特点是实现了“类型参数化”,即STL的代码中可处理任意自定义类型的对象,如果不使用模板技术的话,这是一件相当困难的事。也因为这个原因,在最新的java及C#语法中均加入了对模板语法的支持,可见其重要性。另外一个有关STL重要的话题是GP(Generic Programming),泛型。这是与面向对象相并列的另外的一个编程模型,它以模板为基础,弱化了实体类型的差异,简化了编程时问题抽象的模型,提供了更好的封装性和弹性,对于繁杂的面向对象编程毫无疑问是一种解脱,至少是精神上的。GP是最近几年软件架构的一个研究热点,但国内真正的应用似乎并不多见。
"ATL":Active Template Library,活动模板库,这在VC编程下应该算是比较高级的话题了,它集COM和模板技术于一身,带来了极方便的组件编写方法和极高的学习门槛。可以说,进入ATL领域就算是进入了中高级编程领域。ATL是为组件而生,它的目的是为了让程序员更方便地编写组件(纯用C++写一个最简单的组件实现一个“Hello World”对初学者来说都是很要命的),同时它使用模板技术来类似于MFC一样建立了一个开发COM的框架代码库(模板库),使用该框架及模板库可以快速地进行组件开发。ATL中的一个特点就是你自己的类将成为ATL代码库中某些类的父类,这是一件很有趣的事。
在windows系统中,句柄几乎随处可见。他来源于早期的windows系统, 用来移动进程内存地址空间的碎片但句柄的值不变,方便了对内存的使用和管理。现在的windows系统也广泛的使用它,但功能和作用大大超出了以前。他是一个内部结构(根据系统的不同,ms可能修改它),他被系统定义和管理而能被用户使用。一般来说它是一个指针的指针(一些表的索引),这些索引不能被用户直接访问,当使用一个句柄时,他的内部操作由系统完成。
一个句柄对应一些资源,比如HPEN,HMENU,HDC,HANDLE,HACCEL,HDWP(不常用,管理窗口位置的),HHOOK,HFILE,HKEY等等。一个更完整的列表参考msdn: Win32 Simple Data Types.
资源使用完需要回收。一般可以用CloseHandle api关闭句柄。有些句柄系统自动回收,不需要用户手动去关闭它,比如HCURSOR等等。写起来真难啊,心里的话越想越多去组织不好。
"DLL":Dynamic Link Library
在windows系统中,DLL同样随处可见。我们随便一个复杂点的程序,基本上需要kernel32.dlluser32.dll,gdi32.dll的支持。dll提供了接口,方便用户调用,内部的实现却由dll自己来负责。
dll的作用主要有一下几点(我的理解,不一定全)。一是节省内存消耗和应用程序大小。一般dll执行体在内存中只有一份,但他的数据对于每个程序都是单独的拷贝,所以节省了内存空间。
二是可以单独的编译测试,dll的更改只需自己重新编译,而不需要整个工程重新编译。替换某个dll也很简单,只需保留原有的接口就可以,而可以修改功能。
三是可以在程序之间共享信息。通过在dll中指定共享段,可以达到在不同的程序之间共享数据。
四是系统钩子中必须使用dll.因为dll映像可以被不同进程加载,所以如果将钩子注入到目标进程需要使用dll,同样可以使用dll共享段在不同进程间来共享信息。像上面的句柄一样,每个dll由系统维护一个引用计数。当引用计数为0时,系统撤销dll.
写一下或许就会知道有些概念的把握自己并不是想像之中的清晰。当自己能够用简明的语言将其介绍出来的时候,你会发现自己的表达能力和对概念的理解都加深了。大家不用太拘束,随便写,随便补充,随便纠正,我会作最后的整理的。估计写起来会越来越难,看谁能够坚持到最后:)
重申:尽量不要用自己无真切体会的空洞的抽象的道听途说的语句,我们努力追求真实。
HANDLE
这其实是一个UINT(随便提一下,初学者往往对VC代码中各种古怪的符号、类型标记/宏等百思不得其解,其实它们大多来自基本类型的#define或者typedef,请将光标移到这些符号上(譬如HANDLE),然后按下F12,编译器自会把你带到它的声明处,反复使用几次,你终会见到它的原貌,然后长吁一口气:原来不过如此而已。没用过的初学者请牢记:F12)。很多初学者把HANDLE与指针的理解混淆,总想知道一个HANDLE代表一个什么对象,我的建议是不要去理解为是某对象的指针,而就是理解为一个整数索引(事实上也是),就好像一个数组的下标一样。Windows系统核心中主要是几张大表,这样一个整数索引就是标记目标(窗口、线程、某DC资源等)在这个表中的位置,供操作系统访问时查询用。DLL
DLL的一个特点就是可以动态加载(顾名思义),即在主程序(我更喜欢称为客户程序)需要该模块时才由操作系统加载到内存。毕竟一个大型应用程序我们经常使用到的功能并不多,这样一些不常用的功能模块(DLL)在程序运行时一般将不被载入,极大地节省了内存开销。DLL同时也是目前最常用的分发模块的方法,便于彼此协作。程序中对DLL的调用主要有两种方法:1 针对使用DEF文件导出函数的DLL,使用API函数LoadLibrary(“DLLModuleName")加载,然后使用GetProcAddress()得到函数指针,进而调用 2当DLL编译选项被设为“MFC扩展DLL”时,可以直接将类、函数等导出,客户程序使用同一份头文件声明,加入对应的lib链接库,即可在客户程序中直接使用DLL中的类或函数,无需LoadLibrary。 注:关于DLL的三种形式(普通,MFC DLL,MFC 扩展DLL)的区别我一时拿不真切,往知情者为我修正补全。
HANDLE 实际上是一个无类型指针
typedef void *HANDLE;
进程: 运行的程序的实体。有自己的地址空间。
线程: 分割 CPU时间的最小单位,没有自己的地址空间,存活于进程中。
由于多线程程序设计在一个进程或者多个进程中存在数据共享、交换等所以在MFC中提供了
CCriticalSection ,CEvent,CMutex等
我这几天正在看多线程程序设计,错误的地方大家一定要:扔鸡蛋
进程不是一个静态概念,所以它也不是"运行的程序的实体",进程是一个动态的概念,包括从进程的创建申请,PCB(Process Control Block进程控制块,一般操作系统实现为一个表格)的创建,地址空间的内存分配,模块代码载入并执行,执行完以后进行撤销,整个过程被称为"进程"。在Win32下,一个进程有4G的逻辑空间。Thread 线程
为了更有效的提高CPU的利用率,更好地实现多任务并发,微软将进程进行进一步分割,实现了CPU任务调度的最小单位:线程。一个进程拥有至少一个线程。我们在实现多任务并发的时候通常是建立一个线程(建立线程的系统开销要小于进程),线程是以我们自己的一个函数作为入口,函数执行完毕自动撤销(当然你也可以在执行过程中强制结束该线程)。顺便提一下,在UNIX下并没有线程这个概念,想来是因为UNIX主要是以多进程的并发服务为主(所以它更适合于做服务器),系统运行时通常已经有了太多的进程,所以没有必要再对进程进行细化,因为这样做甚至会降低系统效率(CPU调度不过来),当然,这是我个人的猜想:)
这是一个最不想谈而又不得不谈又最不好谈的问题。我谈一些我个人当前的看法吧。到目前为止,C语言应该是传播最为广泛的语言,特别在UNIX的世界里依然扮演着主角的位置,在其余如硬件开发,嵌入式系统(如手机)皆有十分突出的表现,即便在win32平台下SDK的开发中也有一席之地。更主要的是它是大多数国内(国外我不敢说)程序员的启蒙语言,通过它许多人才领会了程序的思维。C最大的特点就是快,几乎除了汇编以外效率可以达到最高,而它的灵活性,对硬件的直访性也完全符合程序员自由的天性。如果说学习别的技术尚有犹豫和徘徊,那么学C只有一句话:相信我,没错的!也有许多人主张可以直接学习面向对象语言,我不以为然。面向对象语言对机器模型的抽象十分容易让程序员迷糊,心中难以建立准确的程序运行时的模型。毕竟我们是程序员,不是用户,我们不能把所有的问题都想当然地交给编译器去解决,它也解决不了。至少学习一门面向过程的语言,才能知其所以然。 C++
这是贝尔实验室的又一杰作,同时,也伤透了全球太多程序员的心,脑细胞杀伤力十分之大。C++比大多数初学者想像的都要复杂得多,它基本包括:一个类化了的C语言,模板,标准模板库.很多时候很多人掌握的C++仅仅只是一个类化了的C语言的一个子集(不相信的话,你不妨看看COM本质论的每一章前面的那几行代码,试试看有多少语法是不能看懂的)。更麻烦的是使用C++不得不谈到面向对象的编程风格,这同样比初学者想像的难很多,要有打持久战的准备。而最让我这类C++爱好者忧心的还是它目前在Win平台中的前景,在.net平台上很难找出不用C#而使用C++写新代码的理由:( 。而它的复杂性和目前许多诸如java/C#及一些动态语言(python/ruby)比起来,开发效率显然的低,大有退出上层应用程序开发的趋势。这么一个包含了最多范式的近乎完美的语言,我实在不想放弃。我唯有祈祷在未来C++的路可以走得更远更好一些。补充一句:C / C++ ,这是两种语言,都形成了ISO标准,与编译器无关,与平台无关。
OpenGL是OpenGraphicsLib的缩写,是一套三维图形处理库,也是该领域的工业标准。
计算机三维图形是指将用数据描述的三维空间通过计算转换成二维图像并显示或打印出来的技术。
OpenGL就是支持这种转换的程序库,它源于SGI公司为其图形工作站开发的IRIS GL,在跨平台移植过程中发展成为OpenGL。SGI在1992年7月发布1.0版,后成为工业标准,由成立于1992年的独立财团OpenGL Architecture Review Board (ARB)控制。SGI等ARB成员以投票方式产生标准,并制成规范文档(Specification)公布,各软硬件厂商据此开发自己系统上的实现。只有通过了ARB规范全部测试的实现才能称为OpenGL。1995年12月ARB批准了1.1版本,最新版规范是1999.5通过的1.2.1。
OpenGL被设计成独立于硬件,独立于窗口系统的,在运行各种操作系统的各种计算机上都可用,并能在网络环境下以客户/服务器模式工作,是专业图形处理、科学计算等高端应用领域的标准图形库。主要竞争对手是MS-Direct3D.
微软在Windows NT对OpenGL的支持始于3.51,在Windows9x中的支持始于Win95 OEM Service Release 2。Windows下常用的OpenGL库有两种,MS实现的和SGI实现的,MS-OpenGL调用会自动检测是否存在显示卡制造商提供的ICD(Installable Client DeviceDriver)驱动程序,有则调用ICD中的例程,否则才用CPU进行计算,所以能利用显示卡的OpenGL加速能力。对开发者来说使用方法并没有区别,只是有ICD驱动时更快些。SGI的版本是纯软件实现不能利用硬件加速并且SGI已经在1999年宣布停止支持,但这套库便于调试程序,仍有不少开发者使用。
SGI曾经宣布研发OpenGL++,该图形库最大的特点是面象对象,提供了树形场景支持。后来(1999)SGI宣布与M$合作开发Ferihant,即Windows的下一代图形处理体系,包括DirectX与OpenGL的低级图形处理接口和以场景图支持为特点的高级接口,并且就此停止对其在Windows下的OpenGL实现的支持以示决心。此举世瞩目,大家都以为Windows图形处理快要过上幸福生活了,然而,不久,SGI宣布中止合作,并撤回派出的科学家,Ferihant基本上夭折。SGI 称终止合作的原因是M$不肯积极合作,光想把SGI 的技术合并进DirectX,真正内幕不详。不过以SGI在图形处理界的老大地位来说,还是有几分可信度的,因为M$初支持OpenGL就不积极。
虽然早在WinNT3.51 时代M$就已经实现了它的OpenGL 版本,但不肯随其Windows95 提供,称该API 适合高端应用,而Win95面向一般消费者的用不到,并且在其win3.x下开发的wing 图表库的基础上搞出了GameSDK,即后来的DirectX 库,称这套库是专门为高性能游戏开发设计的,在当时的硬件条件下,这无疑是非常有道理的,并且很快成为Windows环境下游戏开发的标准API 。该库实质上是提供了绕过Windows 直接访问显存的途径,从而很好的解决了GDI 体系性能方面的不足,但由于是以COM接口形式提供的,所以相当复杂,而稳定性也不是很好,所以有人称Direct3D 是为追求速度而不择手段的公司才用的。然而也就在这个时期,三维图形加速卡开始走向商用和家用,另外这时实时三维游戏开始流行,红极一时ID Software 的开始铸辉煌,推出了Doom 、Quake ,相信这两个名字在今天的游戏圈子里应该是无人不知无不晓吧? OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL
OpenGL-- 支持OpenGL OpenGL
OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL--OpenGL
这是是实际开发中一个十分重要的工程手段,几乎是必须的一个Process(过程)
如果你的项目中未进行版本控制,那么通常你的项目规模都十分小
对初学者学习而言,建议在开始进行实践小项目的阶段即进行源代码版本控制,因为这在以后的工作中,是一定会用到。源代码版本控制的基本原理如下:
在服务器端建立该项目的数据库,并保存你选定的项目源文件的第一个版本。之后客户端一般每完成一个无编译错误的版本的时候,进行check in操作,在当前版本保存在服务器端上并成为最新版本(注意,不是覆盖以前的
下面介绍一下我接触过的几种版本控制工具(也是国内用得比较多的): VSS: Visual Sourcesafe
这是微软Visual Studio自带的源代码版本控制工具,它最大的特点就是易安装(与Visual Studio集成在一起,装VC/VB的时候就顺便搞定,不用别外费工夫),使用简单(服务器端设置相对容易,一般稍加摸索就可以轻松搞定,客户端更是只管check in/out),基本功能完善,
这是是实际开发中一个十分重要的工程手段,几乎是必须的一个Process(过程)
如果你的项目中未进行版本控制,那么通常你的项目规模都十分小
对初学者学习而言,建议在开始进行实践小项目的阶段即进行源代码版本控制,因为这在以后的工作中,是一定会用到的。源代码版本控制的基本原理如下:
在服务器端建立该项目的数据库,并保存你选定的项目源文件的第一个版本。客户端任一用户要获得某源文件的修改权利,需进行check out操作。之后客户端一般每完成一个无编译错误的版本想进行保存的时候,进行check in操作,将当前版本保存在服务器端上并成为最新版本(注意,不是覆盖以前的哟)。任一客户端可以方便地得到服务器上的文件的任意版本。一般还都实现了一个重要的功能是版本比较,任一客户端可以利用版本控制工具对某文件的不同版本进行版本比较,它会标记出不同版本的同名文件的不同点,可以较轻易地看出版本内容的演化,这一招很常用。以上假设客户端有足够的权限。下面介绍一下我接触过的三种版本控制工具(也是国内用得比较多的): VSS: Visual Sourcesafe
这是微软Visual Studio自带的源代码版本控制工具,它最大的特点就是易安装(与Visual Studio集成在一起,装VC/VB的时候就顺便搞定,不用别外费工夫),使用简单(服务器端设置相对容易,一般个人稍加摸索就可以轻松搞定,客户端更是只管check in/out),基本功能完善,版本比较很直观(我喜欢)。它的一般特点是某人check out了某版本以后,别人将无法对此版本check out,也就是说同一时间只有一个可以修改某一个文件,这样就避免了不同的人对同一文件的修改造成彼此冲突。但以前似乎有人对我提到过VSS也可以进行同时修改再合并,反正我是没有这样用过(如果你用过的话,麻烦跟贴)。另,VSS可集成于VS环境,但根据我的经验,直接在VC里对版本的check操作,常常不生效,所以最好还是到VSS程序里去进行check操作。补充:单机上也可以使用VSS,这样的好处是在对当前某些文件进行了误操作或大规模地误修改之后,可以恢复到最近的无错误的版本,最大程度地挽回损失。VSS实际应用较普遍,如果你是走Visual Studio路线的话,一定要用一下。 CVS: Control Version Software
这个也是一个大名鼎鼎的开源的版本控制工具,主要活跃在UNIX世界。CVS我使用不多,一般而言好像功能比较偏向于命令行方式(UNIX下开发很多人也都使用着命令行方式)。当然,Windows下面也实现了几个版本的CVS,也可以集成于VS,好像还有一个可以挂接在IE上的,我没试过。CVS的一大特点就是不同的客户端可以同时check同一个文件,最后由程序自动进行版本合并。这似乎挺有用的,不过我没有用过:)著名的开源项目管理网站sf.net也是用的CVS,如果你要和全世界的程序员一起协作开发,CVS是必须要安装的。 Rational Clearcase
这个工具就比较上档次了,Rational公司(现在是IBM)的出品,价格十分昂贵。我最初参加工作的时候用过一小段时间,简单谈一下。这个工具的特点是复杂,安装及设置就十分复杂,我的印像中客户端甚至不得不加入到NT域里面去,导致我在本机的权限都不够,安装新程序都很麻烦,很郁闷(不知道是不是我们公司的相关人员安装设置错了)。对使用而言,它有一个功能挺有用的,就是它能够根据你每次check的版本号,自动生成版本树(一个图表),你可以清晰地看到版本的演化过程。所以严格地说,像CVS/Clearcase这样的才真正称得上“版本”控制,VSS还太勉强。Clearcase的功能十分强大,我不详述了(我还不想出书),较适于大型软件公司实施软件配置管理时采用。虽然它的名气十分之响亮,但我不知道国内有多少公司在真正使用正版的Clearcase这样的工具,想来应该是十分之少。
OpenGL
OpenGL至今颇有一点英雄落寞的味道,这一套标准是实现得如此之好,以至于曾经一度成为游戏界面华丽的标准。它的低落也是一个必然,毕竟在微软的强力打压下鲜有不挫败的。但它曾经能够给微软带来如此的压力,至今也依然在工业界被广泛使用,大多数游戏/显卡依然保留着对它的支持(CS里我喜欢的还是OpenGL)。而它的性能在某些方面与D3D比较,依然占着上风。不幸的是DirectX在不停地向前发展,而它,几乎止步不前了,前景并不光明。OpenGL目前在工业领域应用较为广泛,它的优秀的矢量图的操作性能,华丽的色彩,在专业的图形图像处理领域表现突出。游戏中使用相对以前而言则是越来越少。 DirectDraw & D3D
大凡像样的2维Windows游戏,几乎都是采用此技术来实现显示的。DirectDraw有两种模式:全屏和窗口。其中全屏应用更多一些。在全屏下,DirectDraw有一个十分著名的“换页”技术,即在两个显示页面之间用“交换”来实现显示刷新,这个速度十分地快,只是一个指针的交换,比你用BitBlt复制一屏的像素快太多太多,游戏的高效的动画效果大多源于此技术。DirectDraw主要用于娱乐领域和一些实时显示要求较高的场合,如医疗图像。D3D是目前大多三维游戏的标准采用,我没钻研过,不敢多言。它的效果嘛,玩玩游戏就知道了:)
谢谢 littlestone ^-^
提到UML,在软件工程中也常理解为是IBM提出的软件工程的一系列标准,这一套标准很复杂,真正完全实现这些标准的软件工程很少见,大多是采取的一个子集并结合自己的实际。在这里,我只是把它当作建模语言来看待。这个语言是一种图形语言,主要是作为设计时建模的一种标准的图形模型,便于程序员与程序员、程序员与客户、设计员与代码员之间的沟通,同时它也帮助设计人员将头脑中的基于程序代码的对程序功能的理解形成文档,便于理清头绪,进行下一步编码的工作。换言之,设计过程的产品,可以表现为一些文本文档,或者一些框架代码,或者一些伪代码,但比较标准通用的,是表现为一大堆UML图。UML包括动态图和静态图两大类,其中静态图中的类图最为常用。很多人初学时不知道该怎么做设计,写小软件时常常没有设计过程,其实很简单,把软件的类图画出来就好了。学做设计时未必要找一个像Together或者Rational Rose一样的巨无霸。用一样简单的可以做UML图的工具就好,专门用来画UML图的小工具很多,网上容易找。
2) user handles, exposed by USER32.DLL. Icons, menus, windows, cursors, ...
3) GDI handles, exposed by GDI32.DLL. DC, font, region, DDB, DIB section, pen, brush.
The DestroyCursor function destroys a cursor and frees any memory the cursor occupied. Do not use this function to destroy a shared cursor.谢谢指正。
用到WINDOW操作系统功能的编程。一切WINDOWS程序,最终都要调用操作系统的应用程序编程接口(API),正如DOS编程要用到DOS的中断系统服务例程一样。经典著作是《Window 程序设计》(Charles Petzold)。设计模式(Design Patterns):
问题以及解决问题的方案的核心。面对相同或类似的问题,我们只需使用该方案而不必重复劳动。经典著作当属《设计模式-可复用面向对象软件的基础》(Erich Gamma等)。动态链接库(DLL):
程序代码或资源等的封装形式。一直是WINDOWS操作系统的基础,用于
。扩展程序特性 程序可在运行中跟据上下文相关条件有选择进进行动态装入。
。支持多种编程语言。
。简化项目管理。不同工作组间简单地开发不同DLL就行了。
。节省内存。无论硬件如何降价,软件上内存始终是显得不够的。边写入边复制技术更将此技术发挥至新的高度。
。资源共享。
。解决平台差异。不同平台间的专有部分包装在特殊的DLL中,用时加以选择地装入,将避免程序被操作系统拒绝执行。
。其它。有些特别功能,如大部分钩子,只有在DLL中才能发挥作用。
永远支持OpenGL
永远支持OpenGL
什么叫RTTI,有什么用?
运行时类型识别,参见《深入浅出MFC》P96
在程序中,当我们得到某一个对象的实例或者指针时,大多数时候并不能直接肯定它的类型(都是继承以及类型转换惹的祸),这个时候,依靠VC4.0或更高版本的编译器提供的RTTI支持,调用库函数typeid()即可在运行时获取这个对象的“类型信息”,在一些动态处理中“类型信息”很重要,获取了类型信息以后,你就可以有十分把握地调用该类型的相关操作,或者类型转换,或动态生成。因其重要性,在JAVA和.net库中借助单根继承对此有了更优雅的做法,每一个自object继承的类天然就有了表述自己类型信息的能力(继承的好处),并且容易扩展,现在你需要类型信息的时候,大可直接ask那个对象:tell me, what type are you?它就会告诉你答案。debug & release 可译为调试 & 发行
大家都知道,debug是调试版,release是发行版,区别在于debug版生成的程序中包含大量供调试用的场景代码(不是真正运行需要的),而release一般去掉了这些信息,并进行了些代码优化,所以release版的程序会比debug版的程序小很多,运行速度也快一些。同时,debug版为了便于调试,往往会对调试使用的诊断代码加上DEBUG一类的宏,使得在release下不对这些代码进行编译。正由于两种版本编译使用的源代码的差异(以及release糟糕的优化),常常使得两种版本运行时产生截然不同的效果,一个正常一个崩溃是大多数人都遇到过的。导致问题的可能性很多,注意事项详见以前的诸多讨论贴。另,同一个程序如果DLL之间的链接使用了不同版本(譬如EXE是release版,dll是debug版),有时会无法正常运行,所以我一般的做法是每一个DLL针对不同版本使用两个DEF文件,编译生成不同名的两个文件(debug版文件名后加d),调用时各个版本针对自己的版本调用,这在一定程序下可避免混乱。另,release也是可调试的,在工程设置里把调试信息打开即可。
毕竟这里是CSDN,不是软件学报,理当轻松以对...
下面简述几个软件工程方面的概念: XP:eXtreme Programming 极限编程
这是近几年才时兴起来的开发模型,国内大致是01/02年开始有所宣传。
它主要是针对小型开发团队在开发时间要求紧、需求不稳定的中小项目(大多数软件项目都是这个情况)时使用。它打破了传统软件工程的框架,非常新巧。譬如整个开发过程中几乎无文档,大量使用“卡片”来描述开发计划和内容;没有真正意义上的软件功能规格说明书,取而代之的是一系列可测试的用例;没有独立的设计和测试阶段,它们总是在迭代中增量反复进行;设计:尽可能小和简单;一般没有代码复审(code review),大家共同拥有代码。而它的最显著的一个外在特征是它常使用“成对开发”,即一台机器前坐两个开发人员,共同开发(一个看,一个写),这乍听起来真是蛮有趣的:),它的基本出发点是认为成对开发的效率在一定条件下要高于两个人独立开发的和。不要觉得天方夜谭,在很多项目中,这种做法的有效性已经被证实。
XP的特点我看可以用“快、小、灵”来概括,它和传统瀑布模型(自顶向下)的区别在于它使用迭代增量(设计->代码->测试->设计->代码...)的方式。想法很简单:没有什么目标是可以一开始就容易确定的。用爬山来做一下比喻的话,传统的是在山下研究地图,选好一条路线,然后沿着此路前进,XP则是走一走,停一停,看一看,对一步作出新的选择,在很多时候,这样做会让你选择到更好的捷径。 ICONIX:
这个字相信很多人都没见过,我也记不清是什么字拼起来的了,作为开拓眼界,我还是提一下吧。这是一种界于XP和RUP(Rational Unified Process)之间的开发模型,换言之,它比XP“大”,比“Rup”要小。它采用了UML的一个子集,特点是用例驱动,保持良好的进度跟踪能力。它的目标是用最短的时间来把用例变成代码。具体来说,这种开发模型相对精简的XP而言,更加强调用例的建立、分析和代码化,用例是其中心地位。 RUP:Rational Unified Process
前面已经提到了,相信你已经感觉出它是一个极大极丰富的软件开发模型。它使用完整的UML图,对开发的各阶段(需求、设计、代码、测试、维护)均有十分完善而复杂的标准,就不详述了。一般而言,除了IBM以外,不会有多少公司去完全实现这么一个庞大的模型,中小公司更是心有余而力不足,大多是吸其精华,去其"糟粕",使用其中的一个子集再结合自己公司实践来做。 CMM:Capability Maturity Model 软件成熟度模型
这是卡内基*梅隆大学软件工程研究所(我的专业正是软件工程,所以这也成为我心目中的圣地)的一大力作,一度曾形成了席卷全球软件开发的CMM浪潮。CMM分为五级,大多数软件企业都处于第一级,而得到第五级认证的全球也没有多少,国内去除掉挂羊头卖狗肉的,也是寥若星辰(嗯,比星辰是寥多了)。所以CMM实施一般是从第二级开始,能做到第三级的都是颇有实力的软件公司了。CMM是以Process(过程)为中心的模型,从二级始每一级都有几个Key Process(关键过程),每一个KP又分为若干Key Active(关键活动)。CMM的实施一般不能越级实施,并且每一级的实施通常都要一年以上,所以要达到较高等级是一级很困难的事。另,CMM不仅可用于较大规模公司,同样也可实施于小公司,小项目组(这是很多人所不知道的)。实施视具体情况等级之间可交叉,譬如实施时采用二级的某些KP再加上三级甚至四级的KP,但你只有实施了所有二级的KP,你才能也只能通过二级认证,即便你采用了某些四级的KP。CMM最新发展成果是CMMI(Integration),这主要是新考虑了软件与非纯软件因素的关系(譬如系统),以及团队之间的协作问题。
Winsock 2 SPI允许开发两类服务提供者—传输提供者和名字空间提供者。“传输提供
者”(Transport providers,一般称作协议堆栈,比如T C P / I P)即能够提供建立通信、传输数据、日常数据流控制和错误控制等等功能的服务。“名字空间提供者”(Name space providers)则把一个网络协议的定址属性和一个或多个用户友好名关联到一起,以便启用与协议无关的名字解析方案。服务提供者不外乎就是Wi n 3 2支持的D L L,挂靠在Winsock 2的W s 2 _ 3 2 . d l l模块下。对Winsock2 API中定义的许多内部调用来说,这些服务提供者都提供了它们的运作方式。
在侯sir的<<深入浅出>>中一开始就提出了这个概念,大概的提法是说回调函数是操作系统调用而你永远不要去调用的函数。这个提法让初学者有点望而生畏,以为是一种多么高深而难以领会的系统底层的核心技术。其实不然,这个技术本质很简单,而且很常用。它实质就是函数指针的基本运用(如果不知道什么是函数指针的话,翻翻书)。在一个模块中,有时想让一部分功能由其它模块实现,譬如说一个做显示的模块,它只想实现显示的资源配备,画面的刷新,缩放等,而把画具体实体(譬如圆、多边形)的代码放到别的模块来实现,怎么办呢?用函数指针。在自己的类中放一个画圆的函数指针,使用时由外部为这个函数指针赋值(其实就是指向了一个外部的函数),在自己的代码中直接调用这个函数指针来画就可以了(本模块完全不知道外部模块是怎么画圆的)。那个外部的函数在这里就是回调函数!
在很多系统API中就使用了这种函数回调的方法,让我们开发的代码实现可以嵌入到API的代码实现当中,其实我们就是传了一个函数地址给它而已。换句话说,这些API搭好了某些运行的代码框架,我们来为它具体实现。在自己的代码中这种技术也常常被用到。举个典型的例子,写COM(串口)读写代码时,常常单独实现一个模块来读写串口,而这个模块则开放一个回调函数接口,使得每读完若干字节数据(譬如说自定义通讯数据的一帧)就调用一次这个函数,而这个函数是由上层调用模块实现的,具体进行数据的解析、处理。这就是回调。这有什么好处呢?实现了功能的分离,这个串口模块会有良好的重用性。还不明白的话,请仔细想想:) 守护进程
这个概念我更拿不准了。好像这是指从系统开始一直到系统结束一直在运行,长驻内存的线程。譬如说Win32的很多服务进程,都可以称作守护进程。守护进程往往会获得较高的系统核心等级,使得不容易被kill掉。因其特点,一些病毒,监控程序往往实现为守护进程。当然,这绝不是把程序放到“启动”中可以实现的,那个时候启动,已经太晚。我猜想(没真正做过)要实现的话,可以注入到一些系统核心DLL里,一旦这些DLL启动时激活自己的进程,或者实现为Windows的服务进程,常规编程里很少使用到这个技术。
The term Win32 is used to describe an API that is common to all of the Microsoft 32-bit Windows platforms. These platforms currently include:
Windows 95 and Windows 98
Windows NT
Windows CE
from MSDN 2001:
The Microsoft Win32 Programming Model: A Primer for Embedded Software Developers
没有确定是正确的东西不要乱写上来!
而win16和win64是有的!
请看清楚我的原话:"我一时还真拿不准为什么叫win32了,如有缺失请为我补充",另,我也不认为我写的整段话有什么重大缺失,哪怕我没有解释出32是指32位."微软操作系统在win31及其以前都是DOS系统",这句话的Win31显然是指操作系统Windows3.1, win31,win95,win98都是惯用的对操作系统的简称,我不认为有什么问题.本来很感谢你指出的我的疏漏和不足,并不想多说什么,但是你的语气实在是让人不舒服...