分享
 
 
 

Windows 2000系统编程 (1)

王朝vc·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

第1章纵览Windows 2000

毫不隐瞒地说,我是一个科幻迷。但是,我认为现实中的科幻描述很荒谬可笑。虽然我能

接受存在生物圈和星系帝国的事实,甚至可以接受超光速的星际飞行器,但是我不能接受的是

那么容易地与外星人进行交流。当然,在Star Tr e k中,所有外星人都讲英语。事实上,极少数的

科幻故事涉及到第一次接触外星文化会如何。通常都是外星人通过收音机和电视学英语,要么

它们依靠一台功能强大的翻译机。不管哪种方法都在人们看不见的地方进行,因而不会妨碍故

事的进展。

考虑人们之间的交流。不论与谁交流,不论要讨论什么话题,两人的交流大部分都是不言

而喻的,并不需要表达出来,举个什么例子呢?看下面古怪却正确的句子:

“I saw the Grand canyon while flying to New Yo r k .”(在飞往纽约时,我见到了Grand

Canyon。)

你我都知道,说话者那时正飞往纽约,并看见了Grand Canyon (大峡谷)。但从语法上理解,

这句话意指, Grand Canyon大峡谷正飞往纽约, 且我看见了它!当然是废话,因为大家都知道

Grand Canyon大峡谷是不会飞的。而外星人(或电脑,就此而言)并不知道Grand Canyon是什么。

之所以人们能理解这句话,是因为有每个人了解一些常识。

当你穿越世界上的文化界线时,问题则更糟。多年前,英国报纸上刊载在头条的真实新闻

如下:

“British Left Wa ffles on Falklands”(British Left议论F a l k l a n d群岛的局势。)

通常,美国人会感到惊讶,英国人忘记吃早餐为什么值得报道(他们认为英国人在F a l k l a n d s

忘记吃华夫饼干)。然而,如果你了解在英国发生的事件,就会明白British Left是一个政治党派。

头条新闻在说,他们不能接受F a l k l a n d群岛的局势。

英国的报纸编辑是不是疯了?当然不是。他们简单地认为,读者已经有了这些方面的知识,

而多数美国人却没有。

同样的概念在任何复杂的程序设计中也是正确的。当你与其他人讨论编程问题时,你也应

设想他们了解这些问题。若在大街上拦住一个人,就问为什么P r i n t f连接到代码时会失败。除非

你碰巧遇到C 或C + +程序员,不然对方绝对不知所云。

1.1 新的语言

假定此刻你是C + +程序员。你与其他C + +程序员一样知道某些基础知识。如果老板指派你解

决C o b o l语言中的2 0 0 0年问题,没人指望你能顺利地开始这项工作。C o b o l语言的程序员具有和

C + +程序员不同的知识基础。C o b o l程序员和C + +程序员的交流通常十分困难,每个人都认为如

此。

然而,由于某些原因,操作系统并不能共享这种奢侈。老板们似乎期望你轻易地、不绕弯

路地在U N I X、V M S、M V S、M S - D O S和Wi n d o w s间转换。如果你擅长Wi n d o w s的某个版本,这

格外正确。但事实上,这些任务大相径庭。如果你学习过Windows 3.0下的程序设计,那你就可

以慢慢掌握Windows NT或Windows 2000,但这也是努力的结果。

如果你从其他操作系统转而使用Windows 2000,那情形会相当痛苦。作为一个U N I X的老手,

我目睹了许多朋友从U N I X转向Wi n d o w s的经历。他们通常抱怨Wi n d o w s怎么如此糟糕。

事实上, 3 2位版本的Windows 和U N I X并不是完全不同。但确有差异。丢弃原有的基础知

识并重新开始,确实非常困难。如果有人要求“创建一个新进程”,那么U N I X的权威,就会考

虑fork 而不是C r e a t e P r o c e s s。当然,你能在帮助中查到C r e a t P r o c e s s,但就像出国旅行并使用一

本愚蠢的外语常用手册,这会有几分效果,但不舒服也不方便。所以你需要一些基础知识。

本章的目的是要使每个人从相同的起点开始。这里将给大家展示应该了解的(或许已经知

道的)有关Wi n d o w s的一些内容。这样,你就增加了需要了解的书中其余部分的基本信息。

1.2 Wi n d o w s简史

如果我们回去创建公司并开辟Wi n d o w s操作系统市场,不久之后,我们也许会另谋职业。

Wi n d o w s刚面世时,是有争议的。只有M i c r o s o f t这样的公司才能支撑Wi n d o w s,直到开发出实用

的东西。

Wi n d o w s的问题不全是M i c r o s o f t的过失。不要忘记,那时的计算机只有缓慢的处理器、带

宽窄的总线及容量小得可怜的存储器。Wi n d o w s能运行就很幸运了。只是时机尚未成熟。

I n t e l 3 8 6是第一个P C兼容的处理器,它能处理真正像Wi n d o w s这样的系统。M i c r o s o f t悄悄地

推出命名为Wi n d o w s / 3 8 6的产品,且显示出它的优点。这就是Wi n d o w s的第一个版本,运行良好,

深受大多数人的喜爱。

Wi n d o w s / 3 8 6之后不久, M i c r o s o f t推出Windows 3.0。这是第一个Windows 的商业化版本。

该版本并不是没有共享问题,而是问题没有足以影响到人们购买该产品。由于潜在购买者众多,

软件公司急急忙忙进行Wi n d o w s的程序设计(通常,称作应用程序)。

而后不久,Microsoft 又发布Windows 3.1。这个版本不仅修补了Windows 3.0中的许多程序

错误,而且还引入了许多重要的新特性。许多编程人员首先学习了基于Windows 3.0 或3 . 1的

Wi n d o w s编程。

尽管用户们非常喜欢Wi n d o w s的这些版本,但多数编程人员都不喜欢它们。Wi n d o w s的这

些版本还保留了以前的版本遗留的许多包袱。如内存管理是有缺陷的、分段式存储模式常常令

人生厌、多任务处理还很粗糙并需要涉及到的所有程序协同合作完成。如果任一个程序不合作,

整个系统便会崩溃。1 6位系统的根使其对来自U N I X或其他3 2位操作系统的端口代码相当困

难。

另外,市场压力要求Wi n d o w s的应用程序,即编程人员提供的应用程序。不论好坏,这就是

大多数程序员的起点。

M i c r o s o f t也曾发布过不同版本的Windows 3.1,包括Windows for Workgroups 3.1和3 . 11、

Windows 3.11。从开发角度讲,这些并不重要。

1.2.1 Windows NT

然而,真正的举动是M i c r o s o f t决定何时开发Windows NT。因为M i c r o s o f t深信,如果不是受

以前处理器的限制,Wi n d o w s会更加出色。同时也知道,在连网和分布处理时, Wi n d o w s无法与

U N I X这样的操作系统竞争。

那时,使M i c r o s o f感到焦虑的事情是:其他操作系统或微处理器结构的问世会挤垮Wi n d o w s

和I n t e l硬件平台。M i c r o s o f t确信只有借助N T的灵活性,使其仿效其他操作系统运行于不同硬件

平台,才不致受到影响。

N T的发布可以说毫无生气。它对硬件的需求,远远超过当时人们所具有的硬件环境。在

1 6 M B内存的情况下(而那时很少有内存超过8 M B),仅仅得到最小的性能。同时,还要有C D -

R O M去安装N T,而那时极少数人有光驱(事实上,我买光驱完全是出于安装NT 的需要)。

即使已经具有N T运行所需要的硬件环境,这里仍存在两个主要的问题:缺少设备支持和缺

少应用程序。因此,当时世界上只有少数P C机运行N T,而多数仍运行Wi n d o w s 3 . 1。硬件和软件

的开发商缺少支持N T的动力。当然, N T还可运行多数Windows 3.1的程序,而不是所有的程序

都可以运行。为什么要买N T,难道只是为了运行Windows 3.1的程序吗?尤其, N T需要更多的

费用,并需要昂贵的硬件升级。

然而,M i c r o s o f t仍支撑着N T(就像当初开发Wi n d o w s产品那样),并默默地在几个版本上改

进N T。另外,M i c r o s o f t知道必须要吸引第三方开发商来编制N T的应用程序。

1.2.2 Windows 95

解决上述问题的答案是Windows 95。M i c r o s o f t推出新产品Windows 95替代Windows 4.0。

M i c r o s o f t希望将Windows 95看作Windows NT Lite(体会其特性,而不是其替代品)。然而,实

际上Windows 95更像Windows 3.1。

Windows 95的关键是其名义上支持如同Windows NT一样的编程界面。那么,为什么不编写

运行于Windows 95和N T的程序代码呢?这样会使能运行于N T上的软件大量出现,不是吗?为达

到这个目的,M i c r o s o f t所要做的是使Windows 3.1的每个用户立即购买Windows 95。这形成一些

设计选择,它们在其他方面是难于调整的。

这不仅是一个运作得非常好的战略性工作, 3 2位应用程序的数量激增。那么,已经有了N T

产品的经销商们会如何呢?这不正是为N T打开Windows 3.1市场的大好时机吗?然而事实并非如

此。Windows 95应用程序接口(Application Programming Intertace, API)只是Windows NT应用

程序接口的一个子集,如果了解了这一点,就能编写在两个平台都能运行的代码,但是除非从

开始就有打算,否则编写的代码是靠不住的。在技术上, Windows 3.1 API称作Wi n 1 6的A P I,而

其他版本则使用Wi n 3 2的A P I。不过,在Windows 95下的Wi n 3 2与在Windows NT下的Wi n 3 2并不

完全是一回事。

然而,从Windows 3.1程序转到新的Windows 95/NT API显得突然。许多程序员都趋之若骛。

对于那些仍执迷于Windows 3.1的用户,M i c r o s o f t为开发者开发了称作Wi n 3 2 S的产品。如果在程

序中使用了Wi n 3 2 S的库,则会形成一个很小的Windows NT命令子集。Wi n 3 2 S库会自动地将其转换成Windows 3.1式的命令。理论上,代码的一部分可以运行在Windows 3.1、Windows 95和Windows NT上。事实上,Wi n 3 2 S失败了。部分原因是其运行不稳定,另外的原因是实际上构成的命令子集

非常小,并对开发者的限制太多。虽然仍有少数开发者在改善Wi n 3 2 S,最终M i c r o s o f t还是放弃

了它。

总而言之,M i c r o s o f t的战略是非常成功的。也能运行于N T的Windows 95的应用程序在各地

发展起来。突然发现,人们可以在Windows NT上运行真正的3 2位程序了。

1.2.3 其他方面

与此同时,硬件方面的技术发展的也相当快。奔腾( P e n t i u m)级的处理器已成为标准,内

存的价格迅速下跌。高性能视频卡和打印机也已具有8 M B的随机存储器(Random Access

M e m o r y, RAM),许多人的P C机装上6 4 M B或更大的R A M。这些P C机足以满足运行N T的要求,

因此许多人开始转而使用NT 3.5或NT 3.51。多处理器的主板价格的下跌,更刺激人们转向使

用N T。(在多处理器系统上,运行Windows 95是一种浪费,因为Wi n 9 5任何时候都只使用一个处

理器)

I n t e r n e t的蓬勃发展更激发了人们使用N T的兴趣。N T是一个相当不错的网络服务器平台,最

重要的是M i c r o s o f t在N T服务器软件包中包含了I n t e r n e t工具。

Windows NT 3.51的唯一问题是,从用户角度看,它的外观和运作太象Windows 3.1了。许

多用户更喜欢Windows 95 的界面风格、即插即用、及仅适用于Windows 95 的其他特点。

Windows NT 4.0的发布,则带给N T用户更多这方面的东西(和一些新功能)。

对于Windows 2000,M i c r o s o f t带来更多的用户所希望的Wi n d o w s特性(如支持多台监视器),

并为编程人员新增了不少新工具。时至今日,大多数(并不是所有)的家庭用户使用Wi n d o w s

9 5或Windows 98。大多数公司用户,开发者和超级用户(也不是所有的)在运行Windows NT,

并可能转而使用Windows 2000。

1.3 Wi n d o w s版本

Wi n d o w s的每个版本都有不同的风格。多数情况,编程人员并不在意他们使用哪个版本。不

同风格间的主要区别是M i c r o s o f t在磁盘上放置的额外软件和许可证号(像协作用户所允许的号

码)。

单桌面用户的首选是专业版( Professional Edition )。它包含作为个人操作系统而使用

Wi n d o w s所需的全部功能。甚至可以用专业版构成一个小型的网络。

如果要使Wi n d o w s运行在网络或We b服务器上,则应选择服务器版( Server Edition)。根据

需要,服务器产品有几个版本(例如, Site Server提供M i c r o s o f t个人化系统和用于大容量We b站

点的工具)。

最后,Windows Advanceed Server和Datacenter Server使程序潜在地寻址更大的虚拟空间。

Wi n d o w s的这些特殊版本都提供了先进的联网特性和支持附加的多进程处理。

然而,作为编程人员,这些版本的Wi n d o w s之间没有真正的差别。可以用同样的方法,使用

同样的工具,做相同的调用。如果依靠额外的组件(或3 G B虚拟内存的限制),则也许需要特殊

的版本,但通常情况,不必在意程序必须运行于哪一种Wi n 3 2的平台上。

1.4 Wi n d o w s体系结构

从编程人员的观点, Windows 2000提供了相当简单的环境。每个程序都有一个地址范围从

0到2G B的平面(非分段式的存储结构)存储空间。当然,大部分程序并没有全部使用此空间,

的确,今天并不是所有系统都有那么充裕的硬盘空间和物理存储空间。但这不是问题,因为

Wi n d o w s只有在程序使用时才分配其真正的存储空间。

地址是从0到4 G B的3 2位整数值(尽管只有0到2GB有效)。你不必担心使用老版本的

Wi n d o w s的分段结构,跟踪内存或其他古怪的事情。

顺便指出, P e n t i u m处理器允许寻址到4 G B的空间。然而,操作系统保留了2 G B的最高限

制。操作系统真能用到那么大的空间吗?不,能够运行Wi n d o w s的处理器有2 G B的用户程序空

间和2G B的操作系统监控程序空间。因此这种模式与微处理器匹配得非常好。

Windows API是系统的标准接口。我们可以构成针对操作系统的调用命令,而操作系统实际

上寄存于系统动态链接库( Dynamic Link Libraries, DLL)。如果使用其他操作系统,这些命令

则与之不同,但是功能相同。这些功能包括分配存储空间、打开文件等等。这些特性主要被人

们用来编写程序设计语言(像C + +)。你将经常使用程序语言中的结构去实现上述功能。例如,

你大概不会调用Windows API中的C r e a t e F i l e,而会调用C + +库中的f o p e n。另一方面,C r e a t e F i l e

可以实现f o p e n不能处理的某些功能。

如果你有先验的Wi n d o w s编程经验,就会发现这些函数的命令有几分相似。许多函数与

Windows 3.1及更早的版本中的调用函数相同。而另一些有些细微的差别。有时, M i c r o s o f t稍微

改变命令的名字,以表示其参数或返回值存在不同。对名字的常见改动是在其尾部加上E x。这

样,在Windows 3.1 中使用G e t C u r r e n t P o s i t i o n,而在Windows 2000 (或N T)中则使用

G e t C u r r e n t P o s i t i o n E x 。它们有什么不同呢?当两个1 6位字表示的3 2位字返回值时,

G e t C u r r e n t P o s i t i o n返回当前描述的位置。而G e t C u r r e n t P o s i t i o n E x则返回作为变元传送的指针结

构中的两个3 2位字。这些函数有相同的目的,而Wi n 3 2变量则以3 2位运作。

另外的改变发生在接收字符串的任一函数中。N T和Wi n 2 0 0 0内部不使用A N S I字符串。取而

代之,它们使用称作U N I C O D E的1 6位的字符(且后者使用的更多)。然而,大多数程序使用

A N S I(或考虑8位的A S C I I字符)。所以接收字符串每个函数有两种情况:其一给出A N S I字符串

(并将其转换为U N I C O D E),另一种则直接接收U N I C O D E字符串。

例如,考虑Windows 3.1的函数M e s s a g e B o x。大家知道,这个函数弹出带文本字符串的对话

框,Wi n 3 2没有此函数。但它有M e s s a g e B o x A给出A N S I变元及M e s s a g e B o x W处理U N I C O D E。

然而,文档也引用M e s s a g e B o x。这是因为C + +编译器和许多其他工具根据涉及U N I C O D E的优

先权,来选择正确的结果。在C + +程序中,当引用M e s s a g e B o x时,根据对编译器的指令,使用

的扩展为M e s s a g e B o x A和M e s s a g e B o x W宏。当然,这意味着编译器的错误信息涉及到哪个函数

会被拒绝,例如M e s s a g e B o x A。

1.4.1 实际情况

上节讨论Wi n d o w s体系结构,本节内容却很少。事实上,这些显示属于Wi n d o w s的程序是虚

假的。Windows 2000 (和Windows NT)实际上并不用Win32 API运作。而使用A P I s特殊集,其中

包含执行程序(E x e c u t i v e)。M i c r o s o f t并没有公开执行程序的文档,但确是基本集, M i c r o s o f t及

其授权用户能够用来构建操作系统的A P I。这些执行程序执行所有运作。

然而,用户不直接调用执行程序,而是调用一个子系统。该子系统提供个性化的程序。例

如,Wi n 3 2子系统执行如G e t C u r r e n t P o s i t i o n E x和M e s s a g e B o x A函数,并调用使其工作的执行程

序。还有其他子系统(比如,提出贫乏P O S I X的子系统)。

NT 4以前,Wi n 3 2子系统就像其他子系统一样是一个单独的模块。然而,当NT 4和Wi n d o w s

2 0 0 0面世时,Microsoft 意识到几乎所有程序实际上都要用Wi n 3 2子系统。因此,现在的N T版本

中,Wi n 3 2子系统实际上是执行程序的一部分。对应用程序编程人员来说,这没什么差别,只是

其速度更快些。

执行程序之下是硬件分离层( Hardware Abstraction Layer, HAL)程序。这段软件甚至被普

通编程人员进一步移除。这段代码知道如何执行Wi n d o w s所需的所有机器特定的任务。所以如

果你想将Wi n d o w s输送到其他类型的计算机中,你只需编译Wi n d o w s代码和编写客户的H A L。当

然,为了获得所有代码和文档,就必须得到M i c r o s o f t的同意,因为M i c r o s o f t不公开支持H A L

(或Wi n d o w s源代码)。对于单处理器或多处理器,存在不同的H A L。对于不同的机器体系结构,

如在Power PC中也会找到H A L。

1.4.2 Wi n 9 5与Wi n 9 8

Windows 95和Windows 98(合起来,称Windows 9x)如何适于本形象描述呢?如前所述,

Windows 9x更象Windows 3.1而不象Windows NT Lite 。尽管在Windows 95中提供了大部分

Win32 API命令,但它们中的大多数并没有比Wi n 1 6副本功能强多少。通常,也有例外,如果在

Wi n 1 6中都做不到,那在Windows 95或9 8中也无法实现。

起初,这看起来不可思议。为什么新技术业已成熟时( Windows NT 已研发成功),

M i c r o s o f t仍然发布基于旧技术新产品呢?答案就是市场。Windows 95的一个关键目标是鞭策开

发3 2位的程序。由此,几乎所有Windows 3.1 的用户不得不转而使用Windows 95 。否则,

Windows 95会成为另一个Windows NT一样的牺牲品—没有应用软件的强大系统。

M i c r o s o f t编写Wi n d o w s - O n - Windows (WOW)模块,以使Windows NT运行Windows 3.1的程

序,并令人惊喜。许多重要问题利用Win16 API出现的缺陷和未公布的特性。这些程序在W O W

情况下运行时会失败, W O W是根据文档运转的。

使W O W真正成为Win16 API是棘手的,所以M i c r o s o f t的回答是保留W O W以使它们做应该

做的事。如果程序无法运行,就是存在缺陷。这意味着一些Windows 3.1程序无法运行在N T上。

对Windows 95来说,没人准备采用W O W。家庭用户不大可能更新他们的机器,即使他们也

怀疑一些程序后来无法运行。于是M i c r o s o f t需要把Wi n 1 6子系统复制到Windows 95中。

Microsoft 采用显而易见的解决办法:采用现有的Wi n 1 6子系统。这保证所有现存的Wi n d o w s

3 . 1软件实际上运行在Windows 95下,还能使老的Windows 3.1驱动程序能工作。M i c r o s o f t重写了

完全使用3 2位代码的程序部分,但仅仅是一小部分(特别是字体翻译和内存管理)。

那么,Windows 9x作为3 2位系统会怎么样?由于它包含Win32 API,它将Wi n 3 2命令转换成

Wi n 1 6命令(更象走厄运的Wi n 3 2 S产品)。由于这种措施,使许多N T特性不存在于Windows 9x。

其他特性在Windows 95和N T中也不同。为了适应Wi n 1 6程序,内存设置也有所不同。

该书不是讲述Windows 95 (或延伸到Windows 98 )的。然而,它有助于理解如何适合

Wi n d o w s 2 0 0 0。不要在意有关Windows 95/98的内容,但要了解来自N T家族的显著差别。

1.5 Wi n d o w s的特性与差别

如果用惯了早期版本的Wi n d o w s,或不同类的操作系统,就会发现有关Wi n d o w s 2 0 0 0的奇怪

特性。你也不必为此惊叹不已,而需要逐渐习惯之。当然,我们没有预先安排,只是阐述

Windows 2000是如何工作的。

1.5.1 多任务处理与线程处理

如果使用过U N I X,再使用Windows 2000的多任务处理,也许会有失败感。理由是U N I X

(或其他操作系统)虽有处理多任务的不同方式,但其许多术语是相同的。

在Windows 2000下运行程序时,可以创建进程,这并不奇怪。令人惊奇的是操作系统没有

运行进程的进度表。进程拥有打开文件、内存或其他资源,同时还拥有一个线程。

什么是线程呢?线程( t h r e a d)就是一组处理器寄存器的记录。它了解执行到代码的什么地

方,局部变量放在什么地方。Wi n d o w s安排线程的进度,就好象两次交谈。安排线程进度与安

排进程进度有什么区别呢?那就是每个进程只有一个线程。

然而,设想主线程又创建另一个线程会如何呢?而该线程也许又创建更多的线程。重要的

是Wi n d o w s安排线程进度,而不是安排进程进度。连同来自其他进程的线程,每个线程轮流运

行。

那么,线程和进程有什么差别呢?很简单属于一个进程的所有线程容易进行通信,因为它

们共享内存和其他资源,而属于不同进程的线程不易共享数据或通信。的确,它们可以通信,

但需要进程间通信的方法。

1. 派生

对于以前的U N I X编程人员,另外的困难是缺少派生( f o r k)构造。在U N I X中,派生命令复

制当前进程。两个进程相同,每一个都有一个程序数据的私有拷贝。通常,派生之后,就调用

执行( e x e c )。这将一个新文件装载到一个新进程中,去除原进程的拷贝。对Wi n 3 2 的

C r e a t e P r o c e s s函数来说,作为单个命令,派生与执行是相同的。

但是如果想要复制进程及保存两个复制品时,又会如何? Wi n d o w s不易实现这些。这为什么

是重要的?假设你有一个程序,试图优化塑料球生产进度。这是个实例,因为以特殊顺序生产

塑料球会更经济。换句话说,假设必须生产A、B、C三种塑料制品,以满足订单。如果以从A到

B再到C的顺序生产,将浪费两吨塑料。为什么呢?因为每次都要改变生产的塑料制品,在生产

进程中存在化学混合物残渣,将造成一些浪费。但是当B类制品与A类制品更相似,A类制品与C

类制品没有太大的化学性质上的差别时,情况又怎样呢?那么,当先生产B制品,然后生产A制

品,再生产C制品时,也许只浪费5 0 0磅。

对于这个假设的程序,第一步是阅读所有的顺序及当前产品清单,并使之相互匹配。其余

的事就是必须自己加工。现在,你的程序想要尝试几种优化的策略。每次尝试一个策略,与之

不同U N I X程序可以派生多次,为每个优化方法创建新进程。每个新进程得到一个在第一次运行

时搜集到的数据的私有拷贝。最后,主进程将检验结果,并决定哪种方法最好。

在Windows 2000 中,这将很难做到。你可以使用C r e a t e P r o c e s s开始一个新进程,但是默认

情况下将没有和老程序共有的数据。的确,可以使用共享的存储区域,甚至一个文件,但这样

也不那么简单。

使用线程会怎样呢?这也是一种可能。然而,如果优化方式改变了数据,就不可行了,因

为所有线程共享相同的变量。以派生为例,每一步运行都自动地拥有一个私有数据拷贝。在不

影响相关进程的情况下,每个进程都将改变变量。

有趣的是,由于对于P O S I X子系统是可以做到的执行程序有进行派生的能力。然而没有办

法访问Wi n 3 2的派生处理。请注意:朗讯技术公司的David Korn 已有支持Win32 ( U/Win ) 的

P O S I X库(见w w w. r e s e a r c h . a t t . c o m / s w / t o o l s / u w i n /),其余的就是执行派生。据悉,该库运用

C r e a t e P r o c e s s联合特殊的启动代码,它复制使用进程间通信方法的所有数据。听起来也许有许多

工作,但实际上运行得相当不错。

2. Windows NT与Windows 2000 对Windows 3.1

即使熟悉Windows 3.1,也必须要重新考虑多任务处理。当然, Windows 3.1中没有线程,所

运行的每个程序都是一个进程。由于进程都共享内存和Windows 3.1下的其他资源,它们其实更

像Wi n d o w s线程。

另外的问题是程序如何放弃处理器的控制。在Windows 3.1下,程序执行到它们调用少数系

统函数(GetMessage , PeekMessage或Yi e l d)之一为止。此时,Wi n d o w s会选择中止该程序并恢

复执行另一个。这种相互协作的多任务处理的技术简单地执行和释放程序,而编程人员不必担

心死锁或资源竞争。只要不调用任何特殊函数,就不必担心其他程序抢占正在使用的资源。

这种方案的缺点是,如果程序不调用这些特殊函数,系统就死锁。这就是为什么Wi n d o w s

3 . 1中没有S l e e p命令的原因。如果程序没有进程消息而暂停的话,系统的其他部分就会挂起。

Wi n d o w s使用抢先的多任务处理。还可能通过执行某些命令,使自己睡眠。然而,如果不执

行这些命令,Wi n d o w s最终总置于睡眠状态。

这是好事,对不对?大多数情况下是如此。它防止由于运行错误程序而死机。也使系统对

用户做出更快的响应。但对编程人员来说,这增加了额外的负担。假设有几个程序共享一个错

误登录文件。在Wi n d o w s下,可以打开该文件,改写数据并关闭它。只要没有调用任何特殊的

系统命令,就会知道没有其他程序打开该文件(由于没有其他程序能运行)。

Windows 2000就没有这么简单。你可以打开文件,然后放弃(不知不觉地)对另外线程的

控制。如果有线程试图打开相同的文件,会发生什么呢?每个线程都不能打开文件,或以共享

方式打开文件(这不是所希望的)。即便Wi n d o w s没有抢先,也可能有另外的线程执行其他进程,

而引起相同问题。

对于许多操作系统(如U N I X)来说,这是个老问题,其解决方法并不复杂。Wi n d o w s提供

同步对象(见第4章),它能协助解决这类问题。你需要明白,这类问题总会发生。

1.5.2 UNICODE

默认情况下, Windows 2000 不使用A N S I字符,而所有内部字符串都是U N I C O D E。

U N I C O D E是一个1 6位的字符序列(不象A N S I使用8位)。在额外的空间下, U N I C O D E可以容纳

不同的符号和非英语字符。

当然,大多数编程人员(至少在美国)仍使用A N S I。如果你愿意, Wi n d o w s也允许使用

A N S I(至少,多数情况如此)。其技巧是每个接收或返回字符串A P I函数实际上是两个函数:一

个配合U N I C O D E,另一个配合A N S I。当你设置方案时,开发工具(如Visual C++)通常允许你

选择使用哪一个函数。

假定在C + +程序中用到命令M e s s a g e B o x。其编译器根据是否用U N I C O D E模式,定义符号。

头文件为M e s s a g e B o x定义一个宏,并将其扩展为A N S I编译的M e s s a g e B o x A及U N I C O D E编译的

M e s s a g e B o x W。当错误信息和调试输出引用M e s s a g e B o x A时,这将导致混乱。

若要将字符串从A N S I 转换成U N I C O D E ,可以使用Wi d e C h a r To M u l t i B y t e 和

M u l t i B y t e To Wi d e C h a r函数。当然, U N I C O D E字符串并不能完全无误地转换为A N S I字符串,且

Wi n d o w s可能替代一些A N S I不能表示的一些字符。

1.5.3 文件系统问题

Windows 2000利用可安装的文件系统技术。这意味着在同一台机器上,也许会涉及到不同

的文件系统。可能同时在一个硬盘驱动器上使用V FAT(Windows 95的兼容系统),而在另一个

硬盘驱动器上使用N T F S(Wi n d o w s文件系统所选择的)。

通常,只要不设定文件的名字,这些问题就不会困扰你。例如,设定文件的名字包含1个到

8个字符、1个句点、及1个到3个字符,大概会出错。如果将文件的名字视作神秘的、不可知的

字符串,也许就不存在任何问题。

在NT 4以前,可以安装H P F S(O S / 2方式)的文件系统。NT 4撤消了对H P F S正式支持,虽

然在I n t e r n e t上的报告指明,如果需要的话,也可以从NT 3.15安装盘安装之。

值得注意的是, N T F S并不能在软磁盘上运行。NT 3意味着在软磁盘上不能有长文件名。

NT 4和Wi n 2 0 0 0支持V FAT( Windows 95文件系统),它支持长文件名,因此可以在软磁盘上使

用V FAT。然而,仍没有得到N T F S所提供的其他额外特性。

这些特性是什么呢? N T F S是安全的基础。在FAT和V FAT磁盘上不能保护文件的安全。到底

为什么还要FAT和V FAT呢?因为软磁盘很重要,且不能格式化一个N T F S软磁盘(这是不公开的,

如果你真想这样做的话,请见w w w. n t s e c r e t s . c o m)。还有,许多用户会在同一台机器上安装

Windows 95、Windows NT和Windows 2000。如果没有FAT和V FAT,将不能在两个安装程序间

共享硬盘(还有,不公开地, w w w. n t s e c r e t s . c o m具有针对Windows 95的只读N T F S驱动程序)。

你要在N T F S下运行Wi n d o w s,则所有情况都一样。然而,你不能指望它。一些用户正在使

用V FAT或甚至使用H P F S。即然没有临时的本地硬盘,就别指望能从网上发现什么。关键是假

定你对文件名象什么知道的不多。

1.5.4 DLL

动态链接库(Dynamic Link Libraries, DLL)是Wi n d o w s的构架。每次调用系统命令,都将

调用M i c r o s o f t提供的D L L。这使你能够使用代码库,而实际上在链接时程序中并不包含它们。

这有三个优点:使程序更小、不同的程序能共享相同的库、库的更新不需要与程序重新链

接。当然,也可以创建自己的D L L并使用它们。

Windows 3.1 的D L L有许多Win2000 DLL 不能共享的特性。不同于Windows 3.1,Wi n 2 0 0 0

调用D L L中函数,以提示进程何时装载D L L及何时释放D L L。使用D L L为每个进程分配资源是

十分简单的。

当多于一个进程使用一个D L L时,D L L能够专为每个进程设置某个变量,或在进程之间共

享共同的变量。这考虑到共享存储器的未加工的形式,且如果需要在进程间进行通信,是相当

有用的。

当Wi n d o w s试图将D L L装载到程序进程空间时,首先检测是否为其他进程装载了相同的D L L。

若有,Wi n d o w s将简单地尝试将D L L所在相同的内存映射到两个进程中(当然,除去私有的数据

内存)。只有当第二个进程有空闲内存,而在同一地址,第一个进程在使用D L L的情况下,这样

才有效。

如果第二个进程正在使用一些所需要的内存,会怎么样呢?这时, Wi n d o w s必须重新装载

D L L(除非共享内存页)。这意味着两个使用相同D L L的进程,也许对D L L的地址的意见不一致。

这不是个一般问题,如果在共享内存中使用D L L,就会有问题。最后一行:不要将指针指向共

享内存。相反,考虑使用从共享内存首地址起的偏移量。我们将在第6章学习到有关该题目更多

的内容。

1.6 开发工具

Wi n d o w s当然没有开发工具方面的不足。当然, Wi n d o w s的多数开发者的材料都有C + +编程

人员的功劳,这本书也不例外。即使你不打算使用C + +,但几乎所有M i c r o s o f t文档都是用C + +写

的(至少在用其他语言前,都是用C + +),因此,你要逐渐熟悉它。

然而,当然也有许多可行的Wi n d o w s开发平台。例如, J a v a目前很流行。B o r l a n d公司有

Delphi, 可视化的Pascal (及C++ Builder, 它以同样的方式使用C + + )。经常被忽略的语言是Vi s u a l

Basic (VB)。V B显示出真正的编译器,强大的A c t i v e X支持,可以毫不费力地调用A P I。

然而还有不少其他的开发工具,而C + +、J a v a和V B当然是主要的开发工具,可能用来在底

层开发Wi n d o w s。本书中的示例几乎都是用C + +编写的,但本章中的直接解答部分将展示如何从

这三种语言中调用A P I的方法。

结束语

本章展示了寓于Wi n d o w s的一些概念,以及与所熟悉的其他操作系统之间的差别。当你想要

建立知识的基准时,请记住,Wi n d o w s不同于你所熟悉的操作系统,不要拒绝它。

在以下各章中,你会阅读到Wi n d o w s的更多内容,包括本章中主题内容的展开。读完本书,

你自然会接受Wi n 2 0 0 0,信不信由你!

1.7 直接解答

1.7.1 开发工具的选择

当阅读本书有关Wi n d o w s详细内容时,大概会比其他事情更多地涉及到C + +。另一方面,许

多编程人员已经转而使用J a v a,对于大多数设计项目来说,它也是可取的选择。然而,本书中的

大多数示例都是带有类库( M F C)的C + +程序,因为现在看来大多数C + +编程人员总是使用

M F C。你应当可以读懂这些示例(包括程序清单和附录),尽管有些小困难。图形化的用户界面

是不重要的,在那里,可以看到许多写成控制台应用程序的例子。控制台应用程序允许用户编

写C或C + +的代码,它们都带有m a i n函数和标准I / O函数。

另一个令人感兴趣的语言的选择是B o r l a n d公司的Delphi ( 或相关的C++ Builder)。这个编程

环境是高度图形化的,并且完全能够编写底层代码和调用Pascal (Delphi)或C + +(C++ Builder)

语言中的A P I。

尽管Visual Basic很长时间被系统编程人员轻视,但VB6 也是个不错的选择。如果需要使用

A c t i v e X,选择V B 6尤其正确,因为V B 6在构成A c t i v e X方面做了大量的工作。V B 6还提供本地机

的代码编译,并消除了以前V B版本性能上的许多缺陷。你可以容易地调用多数A P I。其主要缺

点是V B程序需要相当大的运行时间库。这也是M F C程序的缺点,但这并不能阻止人们使用

M F C。

不论选择何种语言,都需要能懂构成Wi n d o w s标记的原理。那是本书所讨论内容的真正目的,

尽管多数示例是用C + +语言描述的。

1.7.2 Windows 的体系结构

对应用程序编程人员来说,Wi n d o w s为每个程序提供2 G B的平面虚拟地址空间(有些版本是

3 G B)。通常使用规定的3 2位指针,它可以从0寻址到2 G B。

面向操作系统的命令都保存在动态链接库中( D L L)。这些命令将你的需求传送给Wi n 3 2子

系统,该子系统转而控制Wi n d o w s执行程序,这些执行程序( E x e c u t i v e)则完成实际工作。通

过该点,执行程序则在硬件抽象层( H A L)进一步调用处理操作的机器规定部分。

1.7.3 理解进程

很重要的一点是,不要混淆Wi n d o w s进程和其他操作系统的进程概念。在Wi n 2 0 0 0中,一个

进程就相当于一个容器。那容器又包含什么呢?存储空间、打开文件、资源和线程。线程实际

就是个执行单元,Wi n 2 0 0 0安排线程进度,但不安排进程进度。

一个进程开始于一个线程,该线程能够创建更多的线程(且这些线程又可以创建更多的线

程)。一个进程里的线程共享该进程中的所有东西。它们具有的唯一性是程序中的执行点,以及

在进程地址空间中局部变量的位置。

存在于不同进程中的线程不共享什么资源,除非通过使用规定的进程间通信技术,使它们

共享资源。

1.7.4 从C + +中调用A P I

从多数C + +环境(包括Visual C++),调用A P I相当简单。只要确信包含适当的头文件(通常

是W I N D O W S . H)及有正确的库(通过在线帮助,就可以找到所需要的库)即可。于是就实现

调用。A P I都被设计成符合C / C + +环境。

由于所应用的环境已经设置好一切,使我们可以轻松地调用A P I,所以通常我们无需考虑那

么多。如果你在使用如M F C一样的库,就需要包含如W I N D O W S . H(或其他文件)的库头文件。

要记住,根据在使用A N S I还是在使用U N I C O D E,编译器会在后台改变许多A P I的名字,以

及它们如何做相应的改变。例如, M e s s a g e B o x命令改变为针对A N S I编译的M e s s a g e B o x A及针对

U N I C O D E的M e s s a g e B o x W。当查看映象文件、调试信息、或编译器错误信息时,就可以见到这

些名字。

顺便说一下,从D e l p h i中调用A P I同样很容易。只要包括正确的单元,及用相应的库链接即

可。还有,这些总是设置好的。

1.7.5 从V B中调用A P I

尽管V B通常不调用A P I,但可以利用一些手段来实现V B中调用A P I。诀窍是V B几乎可以调

用D L L中的任何一个函数。由于Wi n d o w s的A P I就是D L L的集合,所以V B能够构成A P I命令。

因为A P I很大,每次运行任何程序的时候,为了了解每个A P I命令,都会降低V B的编程速度。

然而,多数程序仅仅使用少数命令。M i c r o s o f t提供了A P I文本阅读器( API Text Vi e w e r )。使用该

阅读器,可以选取感兴趣的命令,并且该浏览器将它们作为说明( D e c l a r e)报告输送到所选择

的文件中去。这些说明报告使调用A P I成为可能。

这很方便,但也存在一些问题。阅读器并不了解它们之间依赖关系。根据创建输出文件过

程,当试图运行程序时,可能会出错。例如,在下面的语句中,会得到一个错误:

Public Const KEY_EXECUTE = (KEY_READ)

检查文件,就会发现K E Y _ R E A D是在文件的后面部分定义的。因此,你必须手动地将

K E Y _ R E A D的定义向前移动,以使它处于K E Y _ E X E C U T E之前。

另一个问题很类似。仅仅为了找出基于所需要输出的内容,你可以输出一个函数或标识符

(如上述示例中的K E Y _ R E A D)。一旦确定,就有可能发现还需要增加其他项。这样继续下去,

直到挖掘出所有的依赖关系。

1.7.6 从Visual J++中调用A P I

从Visual J++中调用A P I很有挑战性,因为你必须使用J a v e的本机程序界面,它也很棘手。

12 Windows 2000系统编程

然而,M i c r o s o f t的J / D i r e c t却使其变得相当容易。

J / D i r e c t包括两个部分。第一部分可使你调用D L L s中的任意函数而不会有麻烦,第二部分是

调用通用Win32 API的简化方法。

利用第一部分,使用如下J a v a代码的特殊的注释和程序行,能够定义A N S I的M e s s a g e B o x函

数:

/** @d11.import ( "U S E R 3 2") */

private static native int MessageBox ( int w,String msg,String title,int flags );

还能够调用U N I C O D E版本,如:

/** @d11.import ( "U S E R 3 2",unicode) */

private static native int MessageBox ( int w ,String msg,String title,int flags );

当然,不想对整个A P I编写这些语句,所以M i c r o s o f t应用几个类来包装整个A P I。你也许会

如下面语句,来调用M e s s a g e B o x:

com.ms.win32.User32.MessageBox ( 0 ,"H i","Java Message Box ",0 );

这没什么麻烦,U s e r 3 2类照顾所有数据类型的转换和D L L的输入。

1.7.7 Internet资源

这里,给出查阅资料的U R L:

w w w. a l - w i l l i a m s . c o m—作者的站点,每月都会有各种M F C的提示及关于本书的更新内容。

w w w. s y s i n t e r n a l s . c o m—是寻找N T和Windows 2000系统应用程序的网址。

w w w. z d n e t . c o m / p c c o m p / f e a t u r e s / f e a 0 7 9 7 / n t / w e l c o m e . h t m l—来自PC Computing杂志,题目

为“NT Lies”的有趣文章。

(文章整理中待续......)

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有