序:去年为了总结自己所学习/接触过的技术,而在CSDN上完成以下内容(已简单整理),也顺便为初学者少走弯路指明一些方向,可惜后来诸事缠身未能继续,十分遗憾,现放到自己的BLOG上来鼓励自己将此继续下去。
注:以下概念皆是作者凭借自己脑海里对该技术的残留印像即兴而做,故不具备任何学术上的解释精确性和正确性,有理由相信,一个久未接触的技术在自己记忆里所留存的,会比较接近这项技术的本质……
"Win32编程”
很不幸,我从开始学习编程到理解这个名词中间隔了很长的时间(上个世纪的学习环境可见一斑)。很长时间里我都不明白32是指什么,我用过Dos,Win31,win95,win97...但好像没用过名为Win32的操作系统啊?很久以后我才知道,32在这里并不是指操作系统的版本号,而是指32位。微软操作系统在win31及其以前都是DOS系统,windows只是在dos下运行的一个大程序而已。在其后win95则稍有改变,windows除了DOS核心以外也真正成为了操作系统的一部分,提供着各类操作系统提供的服务。应该说,在win95之后的windows(新近的64位win系统以前)都可以称之为win32系统平台(95/98实际上是16与32位混合)。所以在这样的平台上,直接或间接使用系统提供的API编程,就称之为Win32编程。对Visual Studio而言,Win32编程一般指SDK、MFC、ATL这几类开发方法,其中ATL在国内应用不是很广泛,一般应用于以COM组件为架构的中大型软件产品。
"SDK" :Software Development Kit,常译为软件开发(工具)包
在Win32编程领域一般指与MFC这类框架编程相区别的,直接调用Windows提供的API的开发方式,与字面原意有一些区别。另外一个经常见到的说法就是某软件(硬件)带有自己的一套SDK,这里其实一般是指一套API库函数或者类库,供上一层的开发者调用。又譬如常说的DX的SDK,其实是微软开发的一套COM组件,供上层开发者使用。总之,供程序员使用的比较完备的代码库,就可以称之为SDK;
“MFC”: Microsoft Fundation classes 微软基础类库
大家都知道,使用SDK编程方式往往有很多每次都重复的固定不变的一些代码,为了提高编程的效率,减少上千个API带给开发人员巨大的精神压力,微软开发出了这么一个类库,注意,这个类库与操作系统本身无任何关系,它只是对API进行了一个面向对象的封装,当然,还给出了一系列编程的框架。使用SDK的方法,使用Visual Studio,通过调用Windows API,MFC你也可以做得出来。MFC把一些固定不变的代码已经写好了,只在编译时候链上,所以我们的代码里看不到WinMain(),而事实上整个程序的运行,和SDK的方式无任何区别,初学者请记住这一点。另,补充一点个人感想,MFC的初衷,带给开发人员更多的便利,我觉得并不太成功。学习MFC所费的力气和最终的所得,并不太成正比。
"API":Application Programming Interface,应用程序接口
这个词的出现频率很高,从某种意义上来说,也可以看作是SDK的一个子集。这也是做给程序员的程序,不过一般指用导出函数的方式提供服务的函数库,不包括类库和组件。
“GDI”:Graphic Device Interface,图形设备接口
这个是Win32程序下最常用的显示方式,与DirectX、OpenGL处于同一级。在DOS要显示一些东东可不是容易的事,最简单的是调用一些C的图形库函数来实现显示,不过一般也就是些画线,填色,输出几个文字,效果很弱(所以DOS程序界面一般都不怎么样,且实现起来不是一般的复杂),要复杂一点的动画/图片显示什么的,经常要用到的就是硬件中断,调用一些显卡自身的子程序(固化在显卡内的)来做。因为每一个显卡都不同,所以DOS的游戏兼容常常由于显卡的差异而很糟糕。到Windows下大家就幸福多了,Windows将硬件这一层屏蔽起来,用一个表格(Device Context)来代表一个显示,我们要做的就是在这个表格上填好相关参数,然后画上我们想画的东东,然后操作系统会依照这个表格(DC),把相应的显示内容(一般是一块显示内存)传送到指定显卡的指定的显存,再由显卡传给显示屏。我们不再需要与不同的显卡打交通,这是一个十分伟大的胜利!GDI中最常用的是双缓存技术,就是说你可以在内存中创建(也就是复制)一个DC,只不过在这个DC中显示的不再被传送到显示器上。有什么用呢?因为它的各参数是与当前屏幕DC一致的(COPY嘛 ,当然是这个结果),所以它的显示内容可以完整无失真地传送到屏幕DC上。我们通常在内存DC上画图,譬如画一圆,再画一条直线,画完后一次性地传送到屏幕DC上,这样对用户来说屏幕只刷新了一次,可以解决你画一点内容屏幕即刷新一次导致的闪烁问题。当然,双缓冲甚至多缓冲还有很多别的用处,那就要靠自己揣摩了。
"DirectX"
通常简称为DX(读音:低叉)这是个很吸引人眼球的名词,读起来就很上口:)。Windows为我们作了许多屏蔽底层硬件的工作,其中DX是最知名的技术之一。操作系统要与各类硬件打交道,特别是多媒体相关的,譬如显卡、声卡、手柄输入、多媒体流的网络传输等等,这些事情如果都自己来弄的话,那就太要命了(这些一般都涉及系统底层,自己也很难做出来)。而DX则正是这么一套操作系统提供的隔离多媒体硬件与程序员的间质,DX自身一般并不实现处理的能力,它是一个标准,要求硬件来满足,好比DX提供一个函数名,硬件来实现函数内容一样。通过它我们可以非常简单而快速地调用硬件提供的各类服务。它主要包括DirectDraw(通过直接访问显示硬件来提供快速的图象处理能力),DirectSound(提供了软硬件的低延迟声音混频和回放,以及直接访问音频设备的能力),DirectPlay (它明确的提供了通用环境连接能力来简化你应用程序之间的通讯服务),Direct3D(DirectDraw的3D版),DirectInput(简化你的应用程序访问鼠标、键盘和操纵杆设备的能力),DX5.0之后又增加了一些(如DirectShow),不再详述。DX一个重要的特点就是你可以通过它直接访问硬件而无需知道硬件的具体细节。譬如DirectDraw,就能够越过内存而直接访问显存,这样的速度将比GDI快很多,不在一个数量级上。补充一点:DX是以组件的方式提供的,而不是通常的导出API的形式。DX SDK的最新版本是9.0
"COM”:component object model,组件对象模型,一般简称组件。
这是微软为了解决代码重用的一个重要机制。重用代码的最简单办法是源代码重用,把写好的函数和类加到自己当前的代码中,编译即可。简单是简单,敝病却显然的多。另一个常用的方法是单独做成模块,以DLL的形式分发,DLL导出函数或者类,客户程序用动态/静态链接的方法将其加载,这显然比前一种源代码的方法好一些,难度也不大,最为常用。但DLL也有一些不足,最根本的,它不是二进制兼容,DLL版本升级一次就需要与客户程序代码重链接一次,有些时候这几乎是不可能的任务。为了更好地让编程像“搭积木”一样简单,让模块可以完美地配合,完美地替换,COM产生了。COM不是类库,不是代码,不是操作系统的服务,而是一套编程模型,理论上来说,它与语言无关,与操作系统无关,unix下同样可以做COM。COM是一种程序结构模型标准,你做的DLL或EXE在结构上满足这么一个标准,那这个DLL或EXE就是一个组件,它将在该平台上成为二进制兼容。COM主要利用了注册表来登记本模块的信息。客户程序调用时首先查注册表,找到所需组件的位置(这实现了位置透明),然后就用Loadlibrary把它加载进来,这和普通调用没有本质区别,区别在于由于组件特殊的实现方法使得整个过程中用户程序都不知道组件的位置,组件的类的实例化过程,如何销毁,不能直接访问组件的任何实现细节,用户只与组件的几个public接口打交道。这将实现真正的模块之间的独立。对用户程序而言,对于目标组件的认识,除了接口,一无所知。在接口不变的情况下,组件可任意替换而客户程序不作任何改动,无需编译,仅这一点,在中大型程序的模块集成的过程中就将节约相当多的时间。
"STL":Standard Template Library,标准模板库
这是最早由Alexander Stepanov和Meng Lee(蛮像中国人的名字)完成,于1994年提交给ANSI/ISO 标准C++委员会并通过而成为标准C++的一部分。望文生义即可知这是一个代码库标准,不是语法标准。简单地说,STL是以C++中的模板语法为基础建立起来的一套包含基础数据结构和算法的代码库。STL的特点是实现了“类型参数化”,即STL的代码中可处理任意自定义类型的对象,如果不使用模板技术的话,这是一件相当困难的事。也因为这个原因,在最新的java及C#语法中均加入了对模板语法的支持,可见其重要性。另外一个有关STL重要的话题是GP(Generic Programming),泛型。这是与面向对象相并列的另外的一个编程模型,它以模板为基础,弱化了实体类型的差异,简化了编程时问题抽象的模型,提供了更好的封装性和弹性,对于繁杂的面向对象编程毫无疑问是一种解脱,至少是精神上的。GP并不是用来取代面向对象的,而是作为一个有益的补充体,是面向对象很好的合作伙伴。GP是最近几年软件架构的一个研究热点,但国内真正的应用似乎并不多见,这项技术本身还基本处于研究前沿。<
"ATL":Active Template Library,活动模板库
这在VC编程下应该算是比较高级的话题了,它集COM和模板技术于一身,带来了极方便的组件编写方法和极高的学习门槛。可以说,进入ATL领域就算是进入了中级以上的编程领域。ATL是为组件而生,它的目的是为了让程序员更方便地编写组件(纯用C++写一个最简单的组件实现一个“Hello World”对初学者来说都是要命的),同时它使用模板技术来类似于MFC一样建立了一个开发COM的框架代码库(模板库),使用该框架及模板库可以相对方便地进行组件开发。ATL中的一个特点就是你自己的类将成为ATL代码库中某些类的父类,这是一件很有趣的事(这也是模板技术的一个特点)。
"HANDLE": 句柄
这是一个中文翻译很古怪的字,对初学者来说是百思不得其解的东东。这其实等价于void*(顺便提一下,初学者往往对VC代码中各种古怪的符号、类型标记/宏等百思不得其解,其实它们大多来自基本类型的#define或者typedef,请将光标移到这些符号上(譬如HANDLE),然后按下F12,编译器自会把你带到它的声明处,反复使用几次,你终会见到它的原貌,然后长吁一口气:原来不过如此而已。没用过的初学者请牢记:F12)。很多初学者总想知道一个HANDLE代表一个什么对象,我的建议是不要去理解为某对象,而就是理解为访问某一个对象的入口,事实上HANDLE大多数时候是一个整数索引(标志该对象在操作系统的某表中的位置,就好像一个数组的下标一样),Windows系统核心中主要是几张大表,这样一个整数索引就是标记目标在这个表中的位置,供操作系统访问时查询用。偶而它的确是指向某对象的指针,有时它还携带一些额外辅助信息。总之,我们不要去直接访问它,把访问HANDLE的任务交给操作系统好了,除非你还嫌写程序不累:)。
"DLL": Dynamic Link Library 动态链接库
DLL的一个特点就是可以动态加载(顾名思义),即在主程序(我更喜欢称为客户程序)需要该模块时才由操作系统加载到内存。毕竟一个大型应用程序我们经常使用到的功能并不多,这样一些不常用的功能模块(DLL)在程序运行时一般将不被载入,可极大节省内存开销。DLL同时也是目前最常用的分发模块的方法,便于彼此协作。程序中对DLL的调用主要有两种方法:1 针对使用DEF文件导出函数的DLL,使用API函数LoadLibrary(“DLLModuleName" )加载,然后使用GetProcAddress()得到函数指针,进而调用 2 直接将类、函数等导出,客户程序使用同一份头文件声明,加入对应的lib链接库,即可在客户程序中直接使用DLL中的类或函数,无需LoadLibrary。
"Process": 进程
进程是一个动态的概念,包括从进程的创建申请,PCB(Process Control Block进程控制块,一般操作系统实现为一个表格(struct))的创建,地址空间的内存分配,模块代码载入并执行,执行完以后进行撤销,整个过程被称为"进程"。在Win32下,一个进程有4G的逻辑空间。但我们也常把它作为静态概念来使用,在Win32下,一个EXE的执行就是一个进程(如果它内部又开了新进程,另当别论)。
"Thread": 线程
为了更有效的提高CPU的利用率,更好地实现多任务并发,微软将进程进行进一步分割,实现了CPU任务调度的新对像:线程。一个进程拥有至少一个线程。我们在实现多任务并发的时候通常是建立一个新线程(建立线程的系统开销要小于进程),线程以我们自己的一个函数作为入口,函数执行完毕自动撤销(当然你也可以在执行过程中强制结束该线程)。顺便提一下,在UNIX下并没有线程这个概念,想来是因为UNIX主要是以多进程的并发服务为主(所以它更适合于做服务器),系统运行时通常已经有了太多的进程,所以没有必要再对进程进行细化,因为这样做甚至会降低系统效率(CPU调度不过来),当然,这是我个人的猜想:)
"C语言"
到目前为止,C语言应该是传播最为广泛的语言,特别在UNIX的世界里依然扮演着主角的位置,在其余如硬件开发,嵌入式系统(如手机)皆有十分突出的表现,即便在win32平台下SDK的开发中也有一席之地。更主要的是它是大多数国内(国外我不敢说)程序员的启蒙语言,通过它许多人才领会了程序的思维。C最大的特点就是快,除了汇编以外效率可以达到最高,而它的灵活性,对硬件的直访性也完全符合程序员自由的天性。如果说学习别的技术尚有犹豫和徘徊,那么学C只有一句话:相信我,没错的!也有许多人主张可以直接学习面向对象语言,我不太同意。面向对象语言对机器模型的抽象十分容易让程序员迷糊,心中难以建立准确的程序运行时的模型。毕竟我们是程序员,不是用户,我们不能把所有的问题都想当然地交给编译器和操作系统去解决,它们也解决不了。至少学习一门面向过程的语言,才能知其所以然。
C++
这是贝尔实验室的又一杰作,同时,也伤透了全球太多程序员的心,脑细胞杀伤力十分之大。C++比大多数初学者想像的都要复杂得多,它基本包括:一个类化了的C语言,模板,标准模板库.很多初学者掌握的C++仅仅只是一个类化了的C语言的一个子集(不相信的话,你不妨看一看<
源代码版本控制
这是软件开发中一个十分重要的工程手段,几乎是必须的一个Process(过程)。很多作坊式的开发团队在采用软件工程的一些方法的时候,第一个要进行改进或增加的,往往就是这个过程。对初学者学习而言,建议在开始进行实践小项目的阶段即进行源代码版本控制,因为这在以后的工作中,是一定会用到的。
源代码版本控制的基本原理如下:
在服务器端建立该项目的数据库,并保存你选定的项目源文件的第一个版本。客户端任一用户要获得某源文件的修改权利,需进行check out操作。之后客户端一般每完成一个无编译错误的版本想保存的时候,进行check in操作,将当前版本保存在服务器端上并成为最新版本(注意,不是覆盖以前的哟)。任一客户端可以方便地得到服务器上的文件的任意版本(如果有权限的话)。一般还实现了一个重要的功能是版本比较,任一客户端可以利用版本控制工具对某文件的不同版本进行版本比较,它会标记出不同版本的同名文件的不同点,可以轻易地看出版本内容的演化,这一招很常用。
下面介绍一下我接触过的三种版本控制工具(也是国内用得比较多的):
VSS: Visual Sourcesafe
这是微软Visual Studio自带的源代码版本控制工具,它最大的特点就是易安装(与Visual Studio集成在一起,装VC/VB的时候就顺便搞定,不用别外费工夫),使用简单(服务器端设置相对容易,一般个人稍加摸索就可以轻松搞定,客户端更是只管check in/out),基本功能完善,版本比较很直观(我喜欢)。它的特点是某人check out了某版本以后,别人将无法对此版本check out,也就是说同一时间只有一个可以修改某一个文件,这样就避免了不同的人对同一文件的修改造成彼此冲突(注:可通过设置服务器端实现多人check out,但几乎不会这样做,因为那样就失去了VSS的一个最重要的功能)。另,VSS可集成于VS环境,但根据我的经验,直接在VC里对版本的check操作,常常不生效,所以最好还是到VSS程序里去进行check操作。补充:单机上也可以使用VSS,这样的好处是在对当前某些文件进行了误操作或大规模地误修改之后,可以恢复到最近的无错误的版本,最大程度地挽回损失。VSS实际应用较普遍,如果你是走Visual Studio路线的话,一定要用一下。
CVS: Concurrent Versions System
这个也是一个大名鼎鼎的开源的版本控制工具,主要活跃在UNIX世界。CVS我使用不多,一般而言好像功能比较偏向于命令行方式(UNIX下开发很多人也都使用着命令行方式)。当然,Windows下面也实现了几个版本的CVS,也可以集成于VS,好像还有一个可以挂接在IE上的,我没试过。著名的开源项目管理网站sf.net也是用的CVS,如果你要和全世界的程序员一起协作开发,CVS是必须要安装的。在JAVA的世界里,也是以CVS为主。
Rational Clearcase
这个工具就比较上档次了,Rational公司(现在是IBM)的出品,价格昂贵。我最初参加工作的时候用过一小段时间,简单谈一下。这个工具的特点是复杂,安装及设置就十分复杂,我的印像中客户端甚至不得不加入到NT域里面去,导致我在本机的权限都不够,安装新程序都很麻烦,很郁闷(不知道是不是我们公司的相关人员安装设置错了,想来应该是这样,但其复杂性可见一斑)。对使用而言,它有一个功能挺有用的,就是它能够根据你每次check的版本号,自动生成版本树(一个树状图表),你可以清晰地看到版本的演化过程。所以严格地说,像CVS/Clearcase这样的才真正称得上“版本”控制,VSS还太勉强。Clearcase的功能十分强大,我不详述了(我还不想出书),较适于大型软件公司实施软件配置管理时采用。虽然它的名气十分之响亮,但我不知道国内有多少公司在真正使用正版的Clearcase这样的工具,想来应该是十分之少。
OpenGL
OpenGL至今颇有一点英雄落寞的味道,这一套标准是实现得如此之好,以至于曾经一度成为游戏界面华丽的标准。它的低落也是一个必然,毕竟在微软的强力打压下鲜有不挫败的。但它曾经能够给微软带来如此的压力,至今也依然在工业界被广泛使用,大多数游戏/显卡依然保留着对它的支持(CS里我喜欢的还是OpenGL)。而它的性能在某些方面与D3D比较,依然占着上风。不幸的是DirectX在不停地向前发展,而它,几乎止步不前了,前景并不光明。OpenGL目前在工业领域应用较为广泛,它的优秀的矢量图的操作性能,华丽的色彩,在专业的图形图像处理领域表现突出。游戏中使用相对以前而言则是越来越少。新近听说微软的最新操作系统Vista对OpenGL进行了极大的打压,不但性能上折扣,支持的版本也只到1.4(最新版本好像是2.0),不知道最后如何收场,拭目以待。
DirectDraw & D3D
大凡像样的2维Windows游戏,几乎都是采用此技术来实现显示的。DirectDraw有两种模式:全屏和窗口。其中全屏应用更多一些。在全屏下,DirectDraw有一个十分著名的“换页”技术,即在两个显示页面之间用“交换”来实现显示刷新,这个速度十分地快,只是一个显存内一个指针的交换,比你用BitBlt复制一屏的像素快太多太多,游戏的高效的动画效果大多源于此技术。DirectDraw主要用于娱乐领域和一些实时显示要求较高的场合,如医疗图像。D3D是目前大多三维游戏的标准采用,我没钻研过,不敢多言。它的效果嘛,玩玩游戏就知道了:)
UML:Unified Modeling Language,多译为统一建模语言
这个语言是一种图形语言,主要是作为设计时建模的一种标准的图形模型,便于程序员与程序员、程序员与客户、设计员与代码员之间的沟通,同时它也帮助设计人员将头脑中的基于程序代码的对程序功能的理解形成文档,便于理清头绪,进行下一步编码的工作。换言之,设计过程的产品,可以表现为一些文本文档,或者一些框架代码,或者一些伪代码,但比较标准通用的,是表现为一堆UML图。UML包括动态图和静态图两大类,其中静态图中的类图最为常用。很多人初学时不知道该怎么做设计,写小软件时常常没有设计过程,其实很简单,把软件的类图画出来就好了。学做设计时未必要找一个像Together或者Rational Rose一样的巨无霸。用一些简单的可以做UML图的工具就好,专门用来画UML图的小工具很多,网上容易找。补充一点:画UML图不要面面俱到,不要什么都画,突出重点方便理解就好,甚至使用不规范的记号也不要紧(当UML的功能是草稿的时候)。
RTTI: Runtime Type Information 运行时类型信息
在程序中,当我们得到某一个对象的实例或者指针时,大多数时候并不能直接肯定它的类型(都是继承以及类型转换惹的祸),这个时候,依靠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也是可调试的,在工程设置里把调试信息打开即可。
XP:eXtreme Programming 极限编程
这是近几年才时兴起来的开发模型,国内大致是01/02年开始有所宣传。
它主要是针对中小型开发团队在开发时间要求紧、需求不稳定的中小项目(大多数软件项目都是这个情况)时使用。它打破了传统软件工程的框架,非常新巧。譬如整个开发过程中文档很少,大量使用“卡片 (如CRC卡片)”来描述开发计划和内容;没有真正意义上的软件功能规格说明书,取而代之的是一系列可测试的用例;没有独立的设计和测试阶段,它们总是在迭代中增量反复进行;设计:尽可能小和简单;一般没有代码复审(code review),大家共同拥有代码。而它的最显著的一个外在特征是它常使用“成对开发”,即一台机器前坐两个开发人员,共同开发(一个看,一个写),这乍听起来真是蛮有趣的:),它的基本出发点是认为成对开发的效率在一定条件下要高于两个人独立开发的和。不要觉得天方夜谭,在很多项目中,这种做法的有效性已经被证实。
XP的特点可以用“快、小、灵”来概括,它和传统瀑布模型(自顶向下)的区别在于它使用迭代增量(设计->代码->测试->设计->代码...)的方式。想法很简单:没有什么目标是可以一开始就容易确定的。用爬山来做一下比喻的话,传统的是在山下研究地图,选好一条路线,然后沿着此路前进,XP则是走一走,停一停,看一看,对下一步的方向作出新的选择,在很多时候,这样做会让你选择到更好的捷径。
ICONIX:
这个字相信很多人都没见过,我也不知道是什么字拼起来的,作为开拓眼界,我还是提一下吧。这是一种界于XP和RUP(Rational Unified Process)之间的开发模型,换言之,它比XP“大”,比“RUP”要小。它采用了UML的一个子集,特点是用例驱动,保持良好的进度跟踪能力。它的目标是用最短的时间来把用例变成代码。具体来说,这种开发模型相对精简的XP而言,更加强调用例的建立、分析和代码化,用例是其中心地位。
RUP:Rational Unified Process
前面已经提到了,相信你已经感觉出它是一个丰富的软件开发模型。这是由IBM提出来的软件工程模型,它使用完整的UML图,对开发的各阶段(需求、设计、代码、测试、维护)均有十分完善而复杂的标准,就不详述了。RUP本质上是迭代式开发,在每一次迭代中均完成以下四个阶段:初始阶段(inception)、详述阶段(elaboration)、构建阶段(construction)、转换阶段(transition)。
CMM:Capability Maturity Model 软件成熟度模型
这是卡内基*梅隆大学软件工程研究所(我的专业正是软件工程,所以这也成为我心目中的圣地)的一大力作,一度曾形成了席卷全球软件开发的CMM浪潮。CMM分为五级,大多数软件企业都处于第一级,而得到第五级认证的全球也没有多少,国内去除掉挂羊头卖狗肉的,也是寥若星辰(嗯,比星辰是寥多了)。所以CMM实施一般是从第二级开始,能做到第三级的都是颇有实力的软件公司了。CMM是以Process(过程)为中心的模型,从二级始每一级都有几个Key Process(关键过程),每一个KP又分为若干Key Active(关键活动)。CMM的实施一般不能越级实施,并且每一级的实施通常都要一年以上,所以要达到较高等级是一级很困难的事。另,CMM不仅可用于较大规模公司,同样也可实施于小公司,小项目组(这是很多人所不知道的)。实施视具体情况等级之间可交叉,譬如实施时采用二级的某些KP再加上三级甚至四级的KP,但你只有实施了所有二级的KP,你才能也只能通过二级认证,即便你采用了某些四级的KP。CMM最新发展成果是CMMI(Integration),这主要是新考虑了软件与非纯软件因素的关系(譬如系统),以及团队之间的协作问题。CMM在国内的发展似乎有点走向ISO同样的道路,这实在不是一个好消息。
Callback Function: 回调函数
在侯sir的<<深入浅出>>中一开始就提出了这个概念,大概的提法是说回调函数是操作系统调用而你永远不要去调用的函数。这个提法让初学者有点望而生畏,以为是一种多么高深而难以领会的系统底层的核心技术。其实不然,这个技术本质很简单,而且很常用。它实质就是函数指针的基本运用(如果不知道什么是函数指针的话,翻翻书)。在一个模块中,有时想让一部分功能由其它模块实现,譬如说一个做显示的模块,它只想实现显示的资源配备,画面的刷新,缩放等控制功能,而把画具体实体(譬如圆、多边形,都可以有很多种不同效率的实现方法)的代码由别的模块来实现,怎么办呢?用函数指针。在自己的类中放一个画圆的函数指针,使用时由外部为这个函数指针赋值(其实就是指向了一个外部的函数),在自己的代码中直接调用这个函数指针来画就可以了(本模块完全不知道外部模块是怎么画圆的)。那个外部的函数在这里就是回调函数!
在很多系统API中就使用了这种函数回调的方法,让我们开发的代码实现可以嵌入到API的代码实现当中,其实我们就是传了一个函数地址给它而已。换句话说,这些API搭好了某些运行的代码框架,我们来为它具体实现。
XML: Extensible Markup Language 可扩充标记语言
也许你还在为选择.net和j2ee而徘徊不前,如果是这样的话,不妨先着手学一下它们所共通的一个基础:XML。有了HTML为什么我们还要XML?很简单,HTML重在表现文本/图片以及一些多媒体内容,它很难表达数据,因为它的标记是固定的,而数据类型千千万,根本无法描述。.net和j2ee都要解决一个信息传输格式标准化的难题,这个格式要能承载文本/数据,最好还能描述程序接口,同时又应该像HTML一样简单,具有通用性,能够在HTTP下很好的运作。在这种要求下,XML产生了。它的特点正如其名,和HTTP一样,它也是一种标记语言,但是它的标记不是固定的,是可自定义(也就可无限扩展)的,这些自定义标记能够很好的描述数据类型以及对应的数据内容(乍看起来很像数据库表的定义)。除此以外,XML还可以描述程序接口,所以XML可以方便地与网络程序构件(COM、EJB等)直接交互。由于它也是一种ASCII文本流,所以与当前的HTTP兼容,在当前的internet上畅通无阻(这很重要)。有了以上功能,XML就名副其实地成为了新一代互联网技术的标准信息载体,在.net和j2ee的网络架构中,各种“构件”的信息交互都交给了XML,可谓任重而道远。
XML我自己没怎么写过,单就学习上的经验而言,感觉语法上比HTML更琐碎一些,小细节更多,没那么容易速成:) 好在根本同源,有HTML基础甚至WEB开发基础的,学起来也很轻松。
Java2:
这是近几年最吸引大众焦点的语言,在Web开发,网络平台,移动开发的世界里发光发热。你可以不用java,但你不可以不了解java,毕竟这是一个极大且丰富的软件开发领域。有些没使用过java的VS阵营里的人可能还不明白java2里的那个2是什么意思,容我先解释一下。Java最初正式推出1.0时,并没有受到如此多的好评,受到颇多责难,于是它不断地推出新版本来完善自己,其中变化显著的一个版本是1.2(我没记错吧),Java的每一个新版本除了语法上的更新,还有一明显的标志,那就是JDK(Java Development Kit,就是Java自带的一套SDK)的更新,版本1.2以后的java为了在宣传上与以前的java相区别,便被称为java2。目前用得比较多的jdk是1.3/1.4 ,最新的JDK是1.5(代号tiger)。java开发的IDE国内主要以JBuilder为主,另外就是在开源领域如雷贯耳的Eclipse,而sun也力推自己的开源java IDE:Netbeans(从sun的网站上可下载,免费)。Java运行是虚拟机机制,相当于在操作系统上增加了一个软操作系统,源码被编译成一种字节中间码,由虚拟机解释执行,只要有对应的虚拟机,java程序就可以在该操作系统上运行,这就是java号称的一次编译,到处运行的由来。而附带而来的不可避免的性能问题也让Java难以成为桌面程序开发的主流。补充一下:对初学者学习而言最好的Java IDE我推荐使用JCreator,这是一个C++写成的IDE,几MB的大小,比Eclipse快十倍以上的启动速度,对初学者带来极大的便利。
J2EE:
Java实际上又被分为3类:J2EE/J2SE/J2ME,不同类分别对应不同的JDK,J2EE针对企业平台开发,J2SE是标准版,J2ME针对移动平台开发。J2EE现在实在是热得烫手,我前不久翻了一下程序员早期的杂志,发现在第一期创刊号里(2001.1)已经有了j2EE方面的讨论,现在已经是2004.6了,你对它的认知又多了多少?J2EE不是一种单纯的技术,而是一种体系架构以及组成该架构的诸多标准。企业平台开发和桌面/简单Web数据库开发有很大的不同,它的程序规模往往很大(不是一个或者几个EXE可以搞定的),用到的往往是海量的数据库和海量的通信,并且常常是不可中断的,这些特殊性都使得企业平台开发更多地去关注架构的问题。而我们写一个熟悉的java客户端程序,或者消息处理中间件,又或者数据库处理程序,都只是这样一个架构里的一小部分。J2EE是很宠大的,所以请不要写了几个EJB(这是java世界里的构件,概念上大概是类似于COM)的例子程序就感觉自己精通j2EE。
J2EE中传递消息时往往引入了一个被称作消息管理器的中间件,在服务器端使用EJB的容器来管理和调用EJB。在J2EE中一个重要的概念是Transaction(事务)处理,事务的概念最早广泛应用于数据库技术。这实际上是一个封装了很多操作的单元,它的作用是中间任何一个操作失败,可以自动依次整体撤销,所以一个transaction就是操作成功/失败的最小单元,不存在一个transaction只成功了部分操作的情况。
在企业服务平台开发中比较知名的有一个叫BEA公司(这是一家不错的公司,应该知道它的名字),它的产品是Weblogic。
.net
.net是微软为下一个十年准备的技术,你呢?.net也是一种平台技术,而不是单一技术。它主要分为.net运行时平台(对应java的虚拟机)和.net类库(对应java的jdk)。目前只有Windows2003是天然集成了.net运行时平台的操作系统,所以如是你写的.net程序想要在别的操作系统上运行,该操作系统必须先安装.net平台,这是一件蛮烦人的事,也是为什么到目前为止,还没有太多的人改用.net来写程序(尽管可极大提高开发效率)。希望Longhorn的出现可以扭转这一现状。那我们就终于可以和MFC这样过时的框架类库说再见了,一大快事。
.net采用了很多最新的技术和思想,对走VS路线的人来说(特别是有COM概念的),学起来相对轻松且很过瘾,前人推荐的“.net框架程序设计“和”.net本质论“都是很好的书。当然,看它们之前你最好基本掌握一门.net语言,譬如C#,掌握语言对我们来说是最easy的。
聊了这么多技术,下面让我们来放松一下:)
公共密钥: (也常被译为公开密钥)
"密码"已经是一个老少皆知的词,想从银行里把钱取出来吗?没密码可万万不行。不知从什么时候开始,这么一个军事级的词汇已经走进了千家万户,妇孺皆知。不过知道“密钥”这个词的人就少多了,知道“公共密钥”的人就更少了,不但知道而且了解其原理的人则少之又少,当然,如果你以前不清楚的话,那么你即将加入这少之又少的行列:)
long long ago,随着军事的日益发展,情报的重要性日益提高,如何获得准确的情报成为军事上的一大重点,伴随而来的另一个问题则是如何尽量保证自己的情报在被敌人截获后(这总是无可避免的)敌人依然无法获得该情报的信息,防止情报外泄。不妨让我们以今人的智慧来设身处地的想一想,有什么好的解决方法……首先想到的当然是用密文不要用明文,把明文按某种规则打乱为密文、或者让明文与密文有某种一一对应的规则 ,这样即使密文泄露,只要敌人不知道我的明文与密文之间转换的规则,它将一无所获。这是一种简单且行之有效的方法,即便到了近代一战二战中,还被广泛使用着,当然它的这个规则往往是动态的,甚至可能相当复杂。然而这样的方案在理论上有一个重大的缺陷,那就是你如何安全地传递“规则”?两地之间要确保能互相将密文变成明文,必须有共同的规则,那么就至少需要"一次"安全地将“规则”从一地传到另一地,这在理论上是无法保证的,所以整个的安全体系也就无法让人完全地放心,一旦规则泄露,对密文体系的打击则是致命的。有没有什么更好的办法呢?嗯,如果你以前没有接触过的话,我估计你是想不出了。解决的方法正是公共密钥体系。
让我们再回头来看一看我们是如何将明文变成密文的,最简单的是将它重新打乱,或者进行某种线性或非线性变换,立刻就让人难以阅读,但这也是最容易破译的,因为这种自身的变换在数学上相对容易求解,在现在的计算机的帮助下,通过一定量密文明文的统计分析,很容易找到其变化的规则。高级一点的,可以再用一组密码(可以是动态改变的,譬如随日期而改变),让明文与这组密码进行某种组合变化,从而得到一组密文,这样,由于这个“组合变化”可能是非常复杂的一种数学变换,仅通过密文或者加上一定量的明文也很难找出这组密码以及这个“组合变化”的规则。这就是目前绝大多数加/解密的根本原理。而这里的这组密码,我们就把它称作密钥。
但是这只是提高了获得密文者的对密文的破译难度,并没有解决我们前面提出的问题。现在就要来看看“共公(共开)”的含义了。在数学上有一种运算是单向的(在数学理论上截止目前为止),从一个方向算过去很简单,但是它的逆运算当缺少正向运算时加入的一些信息时,就会变得几乎不可能(譬如两个大素数乘起来容易,分解则是十分困难,这就是著名的RSA的原理)。这就构成了我们的“共公密钥”的理论基础。具体使用如下:我们首先产生一对密钥,一把称为加密密钥,一把称为解密密钥,它们是相关但不相同的。加密时我们把明文与加密密钥一起采取“不可逆”数学运算进行“组合变化”,形成密文,解密时把密文与解密密钥一起采取类似的运算进行解密,注意,这处因为加密密钥与解密密钥产生时即是相关连的,所以解密密钥能够完成这样一个“逆运算”。同时,解密密钥也可以用来加密,相应的,加密密解也可以用来解“用解密密钥加密的密文”。具体使用的时候很简单,把加密密钥当作公共密钥,分发给任何想要获取的人,解密密钥由自己妥善保管作为私钥。当拥有加密密钥的人要传递密文给自己时,他只要使用自由获取的我的公共密钥来加密该明文即可,当然,他加密以后他自己也是不能解的,但是传到我手里以后,我则可以用解密密钥来解密,这样就很好地解决了前面提出的无法安全传输“规则”的问题,现在我的公共密钥是公开的,你要拿就拿去好了:) 而私钥我自己好好保存,不用把它放出来。
公共密钥另一个重要作用就是用来签名。我使用私钥对自己的文件加密后,你来使用我发放的公钥来解密,如果解密成功,则可证明这的确是我发出来的文件。
在现在网络信息安全常常使用的证书体系中,“证书”的背后其实也是这样的一种公共密钥体系。
以下为CSDN网友的贡献:
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技术属于数据库访问的高层接口。
HOOK: 钩子
HOOK实际上就是这样一种技术,能够提供一种手段,使程序员能够改变某种事件发生时系统的默认的行为。而应用HOOK技术进行处理较多的就是消息。windows系统捕获一个消息之后会根据消息的类别对消息做不同的处理。如果是驱动程序提供的硬件消息,则放入由系统维护的一个系统消息队列里面,然后在系统内核的帮助下将消息放入某个线程的私有消息队列里面去;如果是其它消息则直接放入对应的线程私有的消息队列里去。每个消息对应一个msg类型的消息结构,用于表示该消息的id,解手者句柄以及传递的额外参数。每个能够响应消息的线程都会有一个消息循环,该循环不断的从其消息队列里面取出消息结构,并根据消息里面包含的接收者窗口句柄调用该窗口对应的窗口函数。这是windows系统对消息进行的默认的处理,而有时我们需要对一些消息进行特殊的处理,不按照系统的流程进行,必须在消息到达目的地消息队列之前截获该消息,加上我们自己的处理,然后根据需要决定是否将消息发往起其最终的目的地。这一个目的是通过系统hook来达到的。
OpenGL:
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 ,相信这两个名字在今天的游戏圈子里应该是无人不知无不晓吧?
袁峰:
Handles are only automatically released when a process ends. User still need to explicitly release HCURSOR. But normally programs do not do that because they only allocate a few HCURSORs. If you're using a lot, you have to release them explicitly.
HANDLE is defined as a void pointer. So it's 64-bit on 64-bit platform.
Usually, the main information of a handle is an integer index into an internal table. But this is not always true. GDI handles have extra information like object type and a re-use count. Some handles are actually pointers.
There are three major groups of handles:
1) kernel handles, exposed by KERNEL32.DLL. Files, thread, process, ..
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.
转贴自qwertasdfg123(无名):
保护模式/实模式:
8086/8088的微机只有一种工作模式(即实模式)只能处理1M以下的地址(16位),这种地址被城为实地址。后来Intel为了突破1M的内存的限制,推出了386等芯片,增加了保护模式,在32位保护模式下,程序可以访问4G内存空间。但同时为了同以前的程序保持兼容,所以旧程序在实模式下运行,而32位程序可以运行在保护模式下,从而最大地发挥服务器的能力。DOS是运行在实模式的,而Windows 9x/NT都是运行在保护模式的。CPU有专门的保护模式指令。
.Net Framework 之 CLR
CLR: Common Language Runtime. .Net Framework的核心。任何面向CLR的语言编译器,如C#,VB.net,J#,Managed C++等生成的结果都是“托管模块”(Managed Module),这是需要CLR才能执行的标准Windows PE(portable executable:可移植可执行)。
面向CLR的语言编译器生成的托管模块包含的重要的一部分就是中间语言(IL)代码,CLR负责在运行时将这些IL代码翻译成本地的CPU指令。
比如生成exe时,在文件的pe文件表头以及组成文件的.text部分会嵌入一些特殊信息。在exe运行时,这些特殊信息将导致CLR的加载并初始化。CLR随后定位到应用程序的入口点,这才启动exe。
com和ole和ActiveX之间是什么关系
比较详细的文章(转载)
熟悉面向对象编程和网络编程的人一定对ActiveX、OLE和COM/DCOM这些概念不会陌生,但是它们之间究竟是什么样的关系,对许多们还是比较模糊的。
在具体介绍它们的关系之间,我们还是先明确组件(Component)和对象(Object)之间的区别。组件是一个可重用的模块,它是由一组处理过程、数据封装和用户接口组成的业务对象(Rules Object)。组件看起来像对象,但不符合对象的学术定义。它们的主要区别是:
1)组件可以在另一个称为容器(有时也称为承载者或宿主)的应用程序中使用,也可以作为独立过程使用;
2)组件可以由一个类构成,也可以由多个类组成,或者是一个完整的应用程序;
3)组件为模块重用,而对象为代码重用。
现在,比较流行的组件模型有COM(Component Objiect Module,对象组件模型)/DCOM(Distributed COM,分布式对象组件模型)和CORBA(Common Object Request Broker Architecture,公共对象请求代理体系结构)。到这里,已经出现了与本文相关的主题COM,而CORBA与本文无关,就不作介绍。之所以从组件与对象的区别说起,是想让大家明确COM和CORBA是处在整个体系结构的最底层,如果暂时对此还不能理解,不妨继续往下看,最后在回过头看一看就自然明白了。
现在开始阐述ActiveX、OLE和COM的关系。首先,让大家有一个总体的概念,从时间的角度讲,OLE是最早出现的,然后是COM和ActiveX;从体系结构角度讲,OLE和ActiveX是建立在COM之上的,所以COM是基础;单从名称角度讲,OLE、ActiveX是两个商标名称,而COM则是一个纯技术名词,这也是大家更多的听说ActiveX和OLE的原因。
既然OLE是最早出现的,那么就从OLE说起,自从Windows操作系统流行以来,“剪贴板”(Clipboard)首先解决了不同程序间的通信问题(由剪贴板作为数据交换中心,进行复制、粘贴的操作),但是剪贴板传递的都是“死”数据,应用程序开发者得自行编写、解析数据格式的代码,于是动态数据交换(Dynamic Data Exchange,DDE)的通信协定应运而生,它可以让应用程序之间自动获取彼此的最新数据,但是,解决彼此之间的“数据格式”转换仍然是程序员沉重的负担。对象的链接与嵌入(Object Linking and Embedded,OLE)的诞生把原来应用程序的数据交换提高到“对象交换”,这样程序间不但获得数据也同样获得彼此的应用程序对象,并且可以直接使用彼此的数据内容,其实OLE是Microsoft的复合文档技术,它的最初版本只是瞄准复合文档,但在后续版本OLE2中,导入了COM。由此可见,COM是应OLE的需求而诞生的,所以虽然COM是OLE的基础,但OLE的产生却在COM之前。
COM的基本出发点是,让某个软件通过一个通用的机构为另一个软件提供服务。COM是应OLE的需求而诞生,但它的第一个使用者却是OLE2,所以COM与复合文档间并没有多大的关系,实际上,后来COM就作为与复合文档完全无关的技术,开始被广泛应用。这样一来,Microsoft就开始“染指”通用平台技术。但是COM并不是产品,它需要一个商标名称。而那时Microsoft的市场专家们已经选用了OLE作为商标名称,所以使用COM技术的都开始贴上了OLE的标签。虽然这些技术中的绝大多数与复合文档没有关系。Microsoft的这一做法让人产生这样一个误解OLE是仅指复合文档呢?还是不单单指复合文档?其实OLE是COM的商标名称,自然不仅仅指复合文档。但Microsoft自己恐怕无法解释清楚,这要花费相当的精力和时间。
于是,随着Internet的发展,在1996年春,Microsoft改变了主意,选择ActiveX作为新的商标名称。ActiveX是指宽松定义的、基于COM的技术集合,而OLE仍然仅指复合文档。当然,ActiveX最核心的技术还是COM。ActiveX和OLE的最大不同在于,OLE针对的是桌面上应用软件和文件之间的集成,而ActiveX则以提供进一步的网络应用与用户交互为主。到这里,大家应该对ActiveX、OLE和COM三者的关系有了一个比较明确的认识,COM才是最根本的核心技术,所以下面的重点COM。
让对象模型完全独立于编程语言,这是一个非常新奇的思想。这一点从C++和Java的对象概念上,我们就能有所了解。但所谓COM对象究竟是什么呢?为了便于理解,可以把COM看作是某种(软件)打包技术,即把它看作是软件的不同部分,按照一定的面向对象的形式,组合成可以交互的过程和以组支持库。COM对象可以用C++、Java和VB等任意一种语言编写,并可以用DLL或作为不同过程工作的执行文件的形式来实现。使用COM对象的浏览器,无需关心对象是用什么语言写的,也无须关心它是以DLL还是以另外的过程来执行的。从浏览器端看,无任何区别。这样一个通用的处理技巧非常有用。例如,由用户协调运行的两个应用,可以将它们的共同作业部分作为COM对象间的交互来实现(当然,现在的OLE复合文档也能做到)。为在浏览器中执行从Web服务器下载的代码,浏览器可把它看作是COM对象,也就是说,COM技术也是一种打包可下载代码的标准方法(ActiveX控件就是执行这种功能的)。甚至连应用与本机OS进行交互的方法也可以用COM来指定,例如在Windows和Windows NT中用的是新API,多数是作为COM对象来定义的。可见,COM虽然起源于复合文档,但却可有效地适用于许多软件问题,它毕竟是处在底层的基础技术。用一句话来说,COM是独立于语言的组件体系结构,可以让组件间相互通信.