600 likes | 882 Views
第十章 WINDOWS 接口控制. 1 、 Windows 环境下编程的基本知识 2 、 Windows 环境下的端口操作 3 、 Windows 操作系统的 API 调用 4 、 Windows 下 DLL 编程技术及应用 5 、 Windows 下的串行通信接口 6 、线程控制技术. Windows 接口控制的必要性. Windows 操作系统为 PC 机用户提供了标准的用户图形界面。其强大的图形处理能力和简单灵便的操作,使很多即使对计算机不是很了解的人也很容易使用计算机,深受广大用户欢迎。
E N D
第十章 WINDOWS接口控制 • 1、 Windows环境下编程的基本知识 • 2、 Windows环境下的端口操作 • 3、 Windows操作系统的API调用 • 4、 Windows下DLL编程技术及应用 • 5、 Windows下的串行通信接口 • 6、线程控制技术
Windows 接口控制的必要性 • Windows操作系统为PC机用户提供了标准的用户图形界面。其强大的图形处理能力和简单灵便的操作,使很多即使对计算机不是很了解的人也很容易使用计算机,深受广大用户欢迎。 • 大多数计算机检测、控制等应用程序的开发,都已转向或逐渐转向Windows环境下的编程。
在Windows环境下实现对计算机硬件资源和内存资源的访问(如端口I/O、DMA、中断、直接内存访问等),对外设的控制和管理是目前工业控制、数据采集系统开发的重要方面。在Windows环境下实现对计算机硬件资源和内存资源的访问(如端口I/O、DMA、中断、直接内存访问等),对外设的控制和管理是目前工业控制、数据采集系统开发的重要方面。 • 本书的第一章到第八章,介绍了DOS环境下用汇编语言和TurbO C语言,利用计算机的硬件资源开发、编写接口控制程序的方法。 • 本章主要介绍在Windows环境下如何实现对计算机的各种接口的控制和访问,以便开发在Windows环境下的控制应用程序。
Windows环境下编程的基本知识 • 1、 处理器的工作模式 • 80X86处理器的工作模式有三种:实模式、保护模式和虚拟86模式。 • 其中实模式和虚拟86模式是为了和早期的8086处理器兼容而设计的,以保证用户早期设计的软硬件资源得以继续使用。 • 计算机系统在不同的环境和条件下在这三种模式中切换工作。
1)实模式 • 80386处理器被复位或加电时,以实模式启动。这时处理器中的各寄存器以实模式的初始化值工作。 • 80386处理器相当于一个快速的8086处理器在工作。虽然80386是32位机,但在实模式时的存储器寻址方式和8086的16位机一样,由段寄存器的内容乘以16做基地址,加上段内的偏移地址形成最终的物理地址。这时候它的32位地址线只使用了低20位,最大寻址空间1MB。
实模式下的中断处理方式和8086处理器一样,也用中断向量表来定位中断服务程序地址。中断向量表的结构也和8086处理器一样,每4个字节组成一个中断向量,其中包括两个字节的段地址和两个字节的偏移地址。实模式下的中断处理方式和8086处理器一样,也用中断向量表来定位中断服务程序地址。中断向量表的结构也和8086处理器一样,每4个字节组成一个中断向量,其中包括两个字节的段地址和两个字节的偏移地址。 • 实模式下80386不支持优先级,所有的指令相当于工作在特权级(优先级0),所以所有的特权级的指令都可以执行,包括读写控制寄存器CR0等。
80386开机时就是在实模式下初始化32位的4个控制寄存器CR0~CR3、48位的全局描述符表寄存器GDTR、16位的局部描述符表寄存器LDTR、48位的中断描述符表寄存器IDTR、任务状态段寄存器TR等管理寄存器及页表等,然后再通过修改CR0寄存器,使其保护模式的使能位PE(位0)置位(=1)而进入保护模式工作的。80386开机时就是在实模式下初始化32位的4个控制寄存器CR0~CR3、48位的全局描述符表寄存器GDTR、16位的局部描述符表寄存器LDTR、48位的中断描述符表寄存器IDTR、任务状态段寄存器TR等管理寄存器及页表等,然后再通过修改CR0寄存器,使其保护模式的使能位PE(位0)置位(=1)而进入保护模式工作的。 • 实模式下不支持硬件上的多任务切换。
2)保护模式 • 当80386工作在保护模式下时,它的所有功能都是可用的。它的32根地址线都可寻址,物理寻址空间高达4GB。 • 在保护模式下,支持内存分页机制,提供了对虚拟内存的良好支持。与8086只可寻址1M的物理地址空间相比,80386可寻址的4G物理地址空间确实是够大的了,但是至今,实际的微机系统仍不可能安装如此巨大的物理内存。因此,为了运行大型程序和真正实现多任务,虚拟内存技术就成为必须的了。
在保护模式下80386支持多任务,可以依靠硬件,仅在一条指令中实现任务切换。任务环境的保护工作是由处理器自动完成的。在保护模式下80386支持多任务,可以依靠硬件,仅在一条指令中实现任务切换。任务环境的保护工作是由处理器自动完成的。 • 在保护模式下,80386还支持优先级机制,不同的程序可以在不同的优先级上运行。 • 优先级分0~3共4个级别。 • 操作系统运行在最高级0上,应用程序则运行在比较低的级别上。 • 配合良好的检查机制后,系统既可以在任务间实现数据的安全共享,也可以很好地隔离各任务。
实现从实模式切换到保护模式,首先要建立保护模式必需的一些数据表,如全局描述符表GDT和中断描述符表等,然后通过修改控制寄存器CR0的控制位PE(位0)来实现。实现从实模式切换到保护模式,首先要建立保护模式必需的一些数据表,如全局描述符表GDT和中断描述符表等,然后通过修改控制寄存器CR0的控制位PE(位0)来实现。 • DOS操作系统运行于实模式下,而Windows操作系统运行于保护模式下。
3)虚拟86模式 • 虚拟86模式是为了操作系统运行在支持多任务的保护模式下,仍能执行8086程序而设置的。 • 虽然80386处理器已经提供了实模式来兼容8086程序,但80386在实模式下的8086程序实际上只是运行得快一些,对CPU的管理还是独占的。 • 而且,在保护模式的多任务环境下运行8086程序时,程序中的很多指令和保护模式的环境是格格不入的,如段寻址方式、对中断的处理和I/O操作的特权问题等。为此,80386处理器又设计了一个虚拟86模式。
虚拟86模式是以任务的形式在保护模式上运行的。虚拟86模式是以任务的形式在保护模式上运行的。 • 在80386上可以同时支持由多个真正的80386任务和虚拟86模式构成的任务。 • 在虚拟86模式下,80386支持任务切换和内存分页。 • 在Windows操作系统中,有一部分程序专门用来管理虚拟86模式的任务,称为虚拟86管理程序。
为了和8086程序的寻址方式兼容,虚拟86模式采用和8086一样的寻址方式,即用段寄存器乘以16做基地址,再配合偏移地址形成线性地址,寻址1MB的空间。为了和8086程序的寻址方式兼容,虚拟86模式采用和8086一样的寻址方式,即用段寄存器乘以16做基地址,再配合偏移地址形成线性地址,寻址1MB的空间。 • 当多个虚拟86任务要运行时,Windows操作系统利用分页机制将不同虚拟86任务的地址空间影射到不同的物理地址上去,使每个虚拟86任务看起来都是在使用自己的1MB地址空间。
8086代码中,有相当一部分指令在保护模式下属于特权指令,如屏蔽中断的cli和中断返回指令iret等。这些指令在8086程序中是合法的。如果不能让这些指令执行,8086程序就无法工作,而要让它执行,操作系统又会出错。8086代码中,有相当一部分指令在保护模式下属于特权指令,如屏蔽中断的cli和中断返回指令iret等。这些指令在8086程序中是合法的。如果不能让这些指令执行,8086程序就无法工作,而要让它执行,操作系统又会出错。 • 为了解决这个问题,虚拟86管理程序采用虚拟的方法来执行这些指令。让这些特权指令执行的时候引起保护异常,虚拟86管理程序在异常处理程序中检查这些产生异常的指令,如果是中断指令,则从虚拟86任务的中断向量表中取出中断处理程序的入口地址,并将控制转移过去;如果是危及操作系统的指令,如cli等,则简单地忽略这些指令,在异常处理程序返回的时候直接返回到下一条指令。
通过这些措施,保证了8086程序既可以正常运行下去,在执行这些指令时又觉察不到已经被虚拟86管理程序作了手脚,而操作系统又不会因执行了这些指令受影响。MS-DOS应用程序在Windows操作系统中就是这样运行的。通过这些措施,保证了8086程序既可以正常运行下去,在执行这些指令时又觉察不到已经被虚拟86管理程序作了手脚,而操作系统又不会因执行了这些指令受影响。MS-DOS应用程序在Windows操作系统中就是这样运行的。
处理器的保护机制 • 80286之前的处理器只支持单任务,操作系统并没有安全性可言,计算机全部的资源包括操作系统的内部资源都可以任凭程序员调用。 • 对于多任务的Windows操作系统,某个程序若随意使用了一些如关中断等影响别的任务执行的指令后,就可能使整个系统陷入瘫痪。所以80286及以上的处理器引入了优先级的的概念。80386处理器共设4个(0~3)优先级。0级是最高级(特权级);3级是最低级(用户级);1级和2级介于它们之间。
特权级代码一般是操作系统的代码,可以访问全部资源;其余级别的代码一般是用户程序,可以访问的资源受到限制。特权级代码一般是操作系统的代码,可以访问全部资源;其余级别的代码一般是用户程序,可以访问的资源受到限制。 • 80386采用保护机制,主要是为了检查和防止低级别代码的越权操作,如访问了不该访问的数据、端口以及调用了高优先级的代码等。保护机制主要由如下几方面组成:
·段的类型检查——段的类型是由段的描述符指定的,主要属性有是否可执行,是否可读和是否可写等。而CS,DS,和SS等段选择器是否能装入某种类型的段描述符是有限制的。如果段类型检查通不过,则处理器会产生一般性保护异常或堆栈异常。·段的类型检查——段的类型是由段的描述符指定的,主要属性有是否可执行,是否可读和是否可写等。而CS,DS,和SS等段选择器是否能装入某种类型的段描述符是有限制的。如果段类型检查通不过,则处理器会产生一般性保护异常或堆栈异常。 • ·页的类型检查——除了可以在段级别上指定整个段是否可以读写外,在页表中也可以为每个页指定是否可读写。对于特权级下的代码,所有的页都是可以写的。但对于1,2,3级的代码,还要根据页表中的R/W项决定是否可读写,若企图对只读的页进行写操作会产生页异常。
·访问数据时的级别检查——优先级低的代码不能访问优先级高的数据段。80386的段描述符中有一个DPL域(描述符优先级),表示这个段可以被访问的最低优先级。而段选择器中含有RPL域(请求优先级),表示当前执行代码的优先级。只有DPL在数值上大于或等于RPL值的时候,该段才是可以访问的,否则会产生一般性异常保护。·访问数据时的级别检查——优先级低的代码不能访问优先级高的数据段。80386的段描述符中有一个DPL域(描述符优先级),表示这个段可以被访问的最低优先级。而段选择器中含有RPL域(请求优先级),表示当前执行代码的优先级。只有DPL在数值上大于或等于RPL值的时候,该段才是可以访问的,否则会产生一般性异常保护。
·控制转移的检查——在处理器中,有很多指令可以实现控制转移,如jmp,call,ret,int和iert等。但在存在多任务的系统中,优先级低的代码不能随意转移到优先级高的代码中去。所以执行到这些指令时,处理器要检查转移的目的位置是否合法。·控制转移的检查——在处理器中,有很多指令可以实现控制转移,如jmp,call,ret,int和iert等。但在存在多任务的系统中,优先级低的代码不能随意转移到优先级高的代码中去。所以执行到这些指令时,处理器要检查转移的目的位置是否合法。
·指令集的检查——有两类指令可以影响保护机制。第一类是能改变全局描述符表GDT、局部描述符表LDT、中断描述符表IDT以及控制寄存器等关键寄存器的指令,称为特权指令;第二类是能操作I/O端口的指令以及cli和sti等能改变中断允许状态的指令,称为敏感指令。·指令集的检查——有两类指令可以影响保护机制。第一类是能改变全局描述符表GDT、局部描述符表LDT、中断描述符表IDT以及控制寄存器等关键寄存器的指令,称为特权指令;第二类是能操作I/O端口的指令以及cli和sti等能改变中断允许状态的指令,称为敏感指令。 • 显然,如果用户级的程序允许用cli禁止一切中断(包括系统时钟中断),那此时整个系统将无法正常运行,所以这些指令的运行要受到限制。特权指令只能在优先级0上才能运行,而敏感指令取决于eflags寄存器中的IOPL位。只有该位表示的优先级高于或等于当前代码段的优先级时,指令才可以执行。
·I/O操作的保护——I/O地址也是受保护的对象。因为通过I/O的操作可以绕过系统对很多硬件进行控制。80386可以单独为I/O空间提供保护,每个任务有个任务段TSS,用来记录任务切换的信息。TSS中有个I/O允许位图,用来表示对应的I/O端口是否可以操作。某个I/O地址在位图中对应数据位为0时表示可以操作;如果为1则还要看eflags中的IOPL位,它表示的优先级高于当前代码段的优先级,才允许访问该I/O端口。·I/O操作的保护——I/O地址也是受保护的对象。因为通过I/O的操作可以绕过系统对很多硬件进行控制。80386可以单独为I/O空间提供保护,每个任务有个任务段TSS,用来记录任务切换的信息。TSS中有个I/O允许位图,用来表示对应的I/O端口是否可以操作。某个I/O地址在位图中对应数据位为0时表示可以操作;如果为1则还要看eflags中的IOPL位,它表示的优先级高于当前代码段的优先级,才允许访问该I/O端口。
Windows的保护机制 • Windows操作系统是个支持多任务的操作系统。 • Windows操作系统的一个重要任务是管理好系统的资源,保证各任务在能正常使用系统资源的同时,又不影响别的任务正常使用系统的资源。
因此,它最首要的宗旨就是“稳定压倒一切”。因此,它最首要的宗旨就是“稳定压倒一切”。 • 任何权限的开放可能引发的安全问题都是很严重的,如在Windows9X操作系统中,中断描述符是用户可写的,CIH病毒可利用它将自己的权限提高到优先级0;而Windows NT下的中断描述符是用户不可写的,CIH病毒在Windows NT下也就无法进驻内存了。
因此,Windiws操作系统干脆设计为尽量为用户程序“安排好一切”。因此,Windiws操作系统干脆设计为尽量为用户程序“安排好一切”。 • 比如对Win32汇编程序来说,整个源程序都不用管各种段寄存器,操作系统已为用户程序的代码段、数据段和堆栈段都预定义好了段描述符。这些段的起始地址都为0,限长都为ffffffff,即可以直接寻找全部的4GB地址空间。程序开始执行时,CS,DS,ES,SS都已经指向了正确的描述符,在整个程序的生命周期内,程序员不必改动这些段寄存器,也不必关心它们的值究竟是多少。 • 这在DOS汇编是不可想象的。
在Windows下,操作系统运行于优先级0,应用程序运行于优先级3。在Windows下,操作系统运行于优先级0,应用程序运行于优先级3。 • 因为Alpha计算机只支持两个优先级,为了便于将应用程序移植到Alpha计算机,Windows操作系统不使用优先级1和2。 • Windows操作系统充分利用了80386的保护机制,所有和操作系统密切相关的东西都是受保护的。
运行于优先级3上的程序有很多限制。 • 如编Win32程序,所有的特权指令都是不可执行的,如lgdt,lldt,lidt指令;对CRx,TRx等寄存器赋值等。代码段是不可写的,数据段只有变量部分的页面是可写的。虽然可以寻找所有的4GB空间,但访问了超出权限以外的东西还是会引发保护异常的。 • 在Windows 98中,系统硬件用到的I/O端口是受保护的,但其余的I/O则可以操作。如用一块地址是300h的插卡,应用程序是可以直接对该端口操作的。但要操作3F8H(串口)和1F0H(硬盘端口)等系统已定义的端口就不行了。 • 在Windows NT中,任何的端口操作都是禁止的。
如果违反了Windows的“保护条例”,处理器会毫不犹豫的把控制权转移到对应的异常处理程序中去。Windows会在处理程序中产生一个“非法操作”对话框把用户的程序判“死刑”。如果违反了Windows的“保护条例”,处理器会毫不犹豫的把控制权转移到对应的异常处理程序中去。Windows会在处理程序中产生一个“非法操作”对话框把用户的程序判“死刑”。 • 在Windows 9x中,系统有时会用一个蓝屏幕来通知用户程序试图访问一个不存在的内存页。 • 如果程序调用的DLL中有错,那麽错误还是会算在应用程序头上,因为DLL的地址空间是被影射到应用程序空间中的。
Windows 9x本身是16位和32位混合的操作系统,为了兼容DOS和Win16程序,很多的保护措施做起来往往力不从心。系统内部往往会出现越权操作,以至蓝屏不断,这就已经不是用户程序问题了。
Windows环境下的端口操作 • DOS环境下编程,需要了解CPU的结构、CPU的工作方式、各种硬件芯片、电路的工作原理、使用系统的端口资源、设计实现要求的电路功能和编程方法,及DOS系统的工作方式等各方面的知识。 • 应用系统的每一个功能的实现,都要设计者亲历亲为。系统中的所有硬件、软件资源,对设计者而言,也都可以随意使用。 • 在Windows环境下,DOS环境下的这些情况发生了根本的变化。
首先,Windows环境下的操作系统在给用户提供了强大的图形功能界面的同时,又把计算机的硬件全部封装到其内核中去。首先,Windows环境下的操作系统在给用户提供了强大的图形功能界面的同时,又把计算机的硬件全部封装到其内核中去。 • 由于其保护模式的存在,系统设计者再也不能象在DOS环境时那样,直接对计算机中的硬件随意编程操作。这对于计算机应用系统设计者而言,使用系统硬件资源是不可回避的、又必须解决问题。 • 以下通过简单的例子,说明Windows环境下用户如何使用系统硬件资源、使用系统硬件资源时可能出现的问题及原因。
Delphi环境下的端口操作 • Delphi具有功能强大的可视化编程环境,是目前Windows环境下应用系统开发的主要工具之一。它由美国Inprise公司提供,经过不断的改进和升级,提供了更加完善的可重用可视化组件库(VCL)和使用更加方便的快速开发工具,众多的功能组件,为编程人员开发各种应用系统提供了很大的方便。Delphi具有运行速度快、功能强、易于学习和使用、开发迅速等特点,只需编写少量的代码就可以快捷地开发出高效的Windows应用程序。
为了方便检测结果,用一段汇编程序为例。它是一个通过对PC机中的8253定时/计数器编程,控制PC机上的喇叭发出一定频率、一定时间音响的程序。在DOS中编译运行后,PC机上的喇叭可发出一秒左右的固定频率的声音。为了方便检测结果,用一段汇编程序为例。它是一个通过对PC机中的8253定时/计数器编程,控制PC机上的喇叭发出一定频率、一定时间音响的程序。在DOS中编译运行后,PC机上的喇叭可发出一秒左右的固定频率的声音。 • 在Windows 98环境下,用Delphi 6的开发环境。经Delphi 6编译、运行,用鼠标点击Form1中的Button1,PC机的喇叭将发出与原来在DOS环境下运行程序时同样频率和时间长度的声音。说明Windows 98环境下对计算机中的端口读、写操作都是成功的。
而同样是这个程序,同样这一台计算机,当进入Windows XP环境下的Delphi 6时执行这程序时,系统立即产生异常类操作保护,弹出如下图10—1所示警告窗口信息。 • 程序停留在开头的 • out 43H,al • 处不能继续执行了。 • 因为Windows操作系统此时认为,对端口的读写必须是具有特权级的指令,不允许用户级的指令对端口进行读和写。喇叭当然也不会响了。由此可见,Windows环境下的端口操作成功与否,是有条件的。
用C++ Builder 6编译、运行这发声程序的结果与 Delphi 6时一样,在Windows 98环境下可以正常工作, Windows XP环境下则不能正常工作。其原因是一样的。因为Windows操作系统此时同样认为,对端口的读写必须是具有特权级的指令,不允许用户级的指令对端口进行读和写。喇叭当然也不会响了。 • 由此可见,Windows环境下的端口操作成功与否,尽管开发工具不同,但同样是有条件的,决定权在Microsoft的Windows操作系统上。
Windows操作系统的API调用 • 1、 API是什么 • Win32指的是32位的Windows操作系统,Win32 API即为Microsoft 32位平台的Windows应用程序编程接口(Application Programming Interface)。所有在Win32平台上运行的应用程序都可以调用这些函数。 • 在Win32 API中,包括了大量的函数、结构和消息等,它不仅为应用程序所调用,它也是Windows自身的一部分,Windows自身的运行也要调用这些API函数。
在DOS下,操作系统的功能是通过各种软中断来实现的。在DOS下,操作系统的功能是通过各种软中断来实现的。 • 在Windows中,操作系统使用动态连接库来代替中断服务程序提供系统功能。 • Windows应用程序所调用的API函数都是在运行时才连接的,而提供这些函数的文件就是动态连接库。 • Windows程序中那些调用API的语句,在DOS程序中就是对软中断的调用。
使用Win32 API,应用程序可以充分挖掘Windows的32位操作系统的潜力。 • Mircrosoft的所有32位平台都支持统一的API,包括函数、结构、消息、宏及接口。 • 使用 Win32 API不但可以开发出在各种平台上都能成功运行的应用程序,而且也可以充分利用每个平台特有的功能和属性。
在具体编程时,程序实现方式的差异依赖于相应平台的底层功能的不同。最显著的差异是某些函数只能在更强大的平台上实现其功能。例如,安全函数只能在Windows NT操作系统下使用。 • 另外一些主要差别就是系统限制,比如值的范围约束,或函数可管理的项目个数等等。
在Windows程序设计领域处于发展初期时,Windows程序员可使用的编程工具唯有API函数。这些函数在程序员手中犹如“积木块”一样,可搭建出各种界面丰富、功能灵活的应用程序。不过,由于这些函数结构复杂,所以往往难以理解,而且容易误用。在Windows程序设计领域处于发展初期时,Windows程序员可使用的编程工具唯有API函数。这些函数在程序员手中犹如“积木块”一样,可搭建出各种界面丰富、功能灵活的应用程序。不过,由于这些函数结构复杂,所以往往难以理解,而且容易误用。 • 随着软件技术的不断发展,在Windows平台上出现了很多优秀的可视化编程环境,程序员可以采用"所见即所得"的编程方式来开发具有精美用户界面和功能的应用程序。这些可视化编程环境操作简便、界面友好,比如:Visual C++,Delphi,Visual Basic等等。在这些工具中提供了大量的类库和各种控件,它们替代了API的神秘功能。
这些类库和控件都是构筑在Windows API的基础上的,但它们使用方便,加速了Windows应用程序的开发,所以受到程序员的普遍采用。 • 有了这些类库和控件,程序员们便可以把主要精力放在整体功能的设计上,而不必过于关注具体细节。 • 不过,这也导致了非常多的程序员在类库面前"固步自封",对下层API函数的强大功能一无所知。
实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。实际上。程序员要想开发出更灵活、更实用、更具效率的应用程序,必然要涉及到直接使用API函数。 • 类库和控件使应用程序的开发容易得多,但它们只提供Microsoft Windows的一般功能。 • 对于一些比较复杂和特殊的功能来说,单使用类库和控件是难以实现的,必须直接使用API函数来编写。 • API函数是构筑整个Windows框架的基石,只有充分理解和利用API函数,才能深入到Windows的内部,充分发挥各种32位平台的强大功能和灵活性,才能成功地扩展和突破类库、控件和可视开发环境的限制。
学习调用API • Win 32 API实际是一种以新的方法代替DOS中的软中断的方式。 • Win 32 的系统功能模块放在Windows的动态连接库(DDL)中,DLL是一种Windows的可执行文件,采用的是和.exe文件同样的PE格式,在其格式文件头的导出表中,以字符串形式指出了这个DLL能提供的函数列表。应用程序要以字符串类型的函数名来指定自己要调用的函数。
Win 32 API的核心由3个DLL提供,他们是: • ·KERNEL32.DLL——系统服务功能。包括内存管理、任务管理和动态连接等。 • ·GDI32.DDL——图形设备接口。利用VGA和DRV之类的显示设备驱动程序完成显示文本和矩形等功能。 • ·USER32.DDL——用户接口服务。建立窗口和传送消息等。 • Win32 API还包括许多其他函数,它们也是由DLL提供。
和在DOS中用中断方式调用系统功能一样,用API方式调用存放在动态连接库DLL中的函数也要约定一个规范,来定义函数的调用方法、参数的传递方法和参数的定义。和在DOS中用中断方式调用系统功能一样,用API方式调用存放在动态连接库DLL中的函数也要约定一个规范,来定义函数的调用方法、参数的传递方法和参数的定义。 • 由于Windows系统的规模和复杂程度比DOS大得多,所以在使用一个API时,带的参数数量多达十几个是常有的事,在DOS中靠寄存器来传递参数的方法显然是不可能了。 • 以下通过一个简单的Win32汇编程序调用API为例说明调用API函数的具体方法。
.386 • .model flat, stdcall • option casemap :none ; case sensitive • include windows.inc • include user32.inc • include kernel32.inc • includelib user32.lib • includelib kernel32.lib • .data • szCaption db 'Win32汇编程序调用Windows API 函数例子',0 • szText db '本简单程序调用的是Windows消息窗口的API函数,要显示的信息在此设定',0 • .code • start: • invoke MessageBox, NULL,offset szText,offset szCaption,MB_OK • invoke ExitProcess,NULL • end start
Windows下DLL编程技术及应用 • 10.4.1 DLL的技术特点 • DLL(Dynamic Linkable Library)称动态连接库。可以说它是由C语言函数库和Pascal库单元的概念发展起来的。
所有的C语言标准库函数都存放在某一个函数库中,同时用户也可以用LIB程序创建自己的函数库。在链接应用程序的过程中,链接器从库文件中拷贝程序调用的函数代码,并把这些函数代码添加到可执行文件中。所有的C语言标准库函数都存放在某一个函数库中,同时用户也可以用LIB程序创建自己的函数库。在链接应用程序的过程中,链接器从库文件中拷贝程序调用的函数代码,并把这些函数代码添加到可执行文件中。 • C语言对应用函数的这种方法,与只把函数存储在已编译的.OBJ文件中的方式相比,显然更有利于程序代码的复用。
对于Windows这样的多任务系统而言,C语言的调用函数库函数这种方法仍显得过于累赘。对于Windows这样的多任务系统而言,C语言的调用函数库函数这种方法仍显得过于累赘。 • 因为多个Windows任务往往都要实现屏幕输出、消息处理、内存管理、对话框等操作,若每个程序都要拥有这些属于自己的函数,多任务的Windows应用程序将出现大量重复的功能代码,整个Windows程序也将变得非常庞大。 • 所以,Windows系统的发展,要求允许同时运行的多个程序能共享一组函数的单一拷贝。