1 / 92

Windows 环境下的程序设计

Windows 环境下的程序设计. Instructor: Hengming Zou, Ph.D. In Pursuit of Absolute Simplicity 求于至简,归于永恒. Windows 环境下的程序设计. 1. Windows 应用程序设计模式 2. 结构化异常处理 3. 动态链接库 4. Windows 驱动程序模型 5. WDM 驱动程序编程实例 6. 开发 WDM 驱动程序的一般方法. Windows 应用程序设计模式. Windows 应用程序是特意为在 Windows 环境中运行而编写的应用程序

jarah
Download Presentation

Windows 环境下的程序设计

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Windows环境下的程序设计 Instructor: Hengming Zou, Ph.D. In Pursuit of Absolute Simplicity求于至简,归于永恒

  2. Windows环境下的程序设计 • 1. Windows 应用程序设计模式 • 2. 结构化异常处理 • 3. 动态链接库 • 4. Windows驱动程序模型 • 5. WDM驱动程序编程实例 • 6. 开发WDM驱动程序的一般方法

  3. Windows 应用程序设计模式 • Windows 应用程序是特意为在Windows 环境中运行而编写的应用程序 • 以窗口为核心的用户界面、以事件驱动为动力的程序运行机制、以及将程序代码与用户界面分开处理的程序开发手段,构成了Windows应用程序特有的设计模式

  4. Win32 API • Windows 应用程序总是在常规的用户态下运行 • 操作系统核心组件则对外界表现出中立的性质,它们不实现用户界面,甚至不提供编程接口,系统服务调用对应用程序而言是不公开的 • Windows操作系统依靠一组用户态环境子系统,作为应用程序与操作系统核心之间的接口

  5. Win32 API • Win32子系统是Windows 操作系统的固有的子系统,这个子系统能够提供应用程序运行所需要的窗口管理、图形设备接口、媒体控制、内存管理等各项服务功能,这些功能以函数库的形式组织在一起,这就是Win32应用程序编程接口,简称为Win32 API • Win32子系统负责将API调用转换成Windows操作系统的系统服务调用

  6. Win32 API Windows应用程序 Windows应用程序 Win32 子系统 用户态 子系统 核心态 系统服务 硬件层 Windows 应用程序与操作系统的关系

  7. Win32 API • USER32.DLL:负责处理用户接口 • GDI32.DLL:负责在图形设备上执行绘图操作 • KERNEL32.DLL:操作系统核心功能服务 • COMCTL32.DLL:通用控件库 • COMDLG32.DLL:公共对话框 • SHELL32.DLL:用户界面外壳 • DIBENG.DLL:图形引擎 • NETAPI32.DLL:网络

  8. Win32 API • 标准Win32 API函数分类: • 系统服务 • 通用控件库 • 图形设备接口 • 网络服务 • 用户接口 • 系统Shell • Windows 系统信息

  9. Windows应用程序设计模式 • 窗口 • 目的是保证用户能够同时访问大多数应用程序 • 应用程序使用窗口来显示输出或接收用户的输入 • 应用程序只有通过窗口才能访问系统显示器;并且通过使用窗口与其他应用程序共享系统显示器

  10. Windows应用程序设计模式 • 事件驱动 • Windows 应用程序的执行顺序取决于事件发生的顺序,描述事件发生的信息称为消息,而事件驱动程序设计则是围绕着消息的产生与处理而展开的 • 消息可以分为由硬件设备产生的输入消息和来自Windows系统的窗口管理消息 • 发送消息——send • 指派消息——post

  11. Windows应用程序设计模式 1 应用程序 Windows WinMain 函数 系统消息队列 硬件输入 消息循环 应用程序队列1 窗口 函数1 窗口 函数m 事件驱动 n 应用程序 WinMain 函数 消息循环 应用程序队列 n 窗口 函数1 窗口 函数m

  12. Windows应用程序设计模式 • Windows应用程序的开发流程 • Windows 应用程序分为程序代码和用户界面资源两部分,两部分通过资源编译器组合为一个完整的EXE文件 • 将用户界面资源一类的静态数据与程序代码相分离有如下一些优点: • 减少内存要求; • 划清了程序员与用户界面设计人员的任务分工 • 用户界面风格的变化可以不必修改程序代码或只需进行少量的修改

  13. 对话框编辑器 字体编辑器 C编译器 Windows应用程序设计模式 • Windows应用程序的开发流程 图象编辑器 .DLG . . BMP . ICO . CUR . FON .C .H .RC . 资源编译器 .RES .DEF .OBJ 工具 文本文件 .EXE . LIB 链接器 二进制文件

  14. Windows应用程序的基本结构 • Windows应用程序具有相对固定的基本结构,入口点函数WinMain和窗口函数构成了Windows应用程序的基本框架

  15. Windows应用程序的基本结构 • WinMain函数 • 是程序的入口点,相当于标准C语言中的main函数 • WinMain函数主要由四部分组成: • 注册窗口类 • 创建窗口 • 显示窗口 • 建立消息循环

  16. Windows应用程序的基本结构 • WinMain函数消息循环 • Windows并不直接把输入消息发送给应用程序,而是将其送入应用程序的消息队列之中。此外,Windows和其他应用程序也可以将消息指派到应用程序队列中 • 应用程序必须读取应用程序队列,检索消息并将它们发送出去,以便适当的窗口函数能够处理它们,负责这一任务的便是消息循环

  17. Windows应用程序的基本结构 • WinMain函数消息循环 • while(GetMessage(&Msg, NULL, 0,0)) • { • TranslateMessage(&Msg); • DispatchMessage(&Msg); • } • GetMessage函数检索到WM_QUIT消息时返回非零值,检索到其他消息均返回

  18. Windows应用程序的基本结构 • 窗口函数 • 窗口函数也称为窗口过程,负责从Windows接收消息,并根据这些消息完成特定的操作 • 窗口函数是一个回调函数,由Windows系统调用,应用程序并不会直接调用它的窗口函数 • 窗口函数的主体是由一系列case语句组成的消息处理程序段 • 如果窗口函数不处理某些消息,则必须把它们传给DefWindowProc函数

  19. Windows系统 指派的消息 发送的消息 WM_KEYDOWN WM_CREATE WM_KEYUP WM_DESTROY WM_MOUSEMOVE WM_SIZE WM_LBUTTONDOWN WM_PAINT WM_QUIT … ... … ... ① DefWindowProc ( ) 应用程序的 消息队列 检索到 的消息 Windows 应用程序的 消息处理过程 ③ ⑤ GetMessage ( ) ② 应用程序 WinMain ( ) DispatchMessage ( ) 消息 循环 ④ 回调 WndProc ( ) case 1 case 2 case 3 … ⑥ Default

  20. Windows应用程序的基本结构 • 当用户关闭窗口时,Windows系统将把WM_DESTROY消息发送给该窗口的窗口函数,在这种情况下,窗口函数应该使用PostQuitMessage函数将WM_QUIT消息发送到应用程序队列中,这样可以使GetMessage函数检索到WM_QUIT消息,从而结束消息循环,退出应用程序

  21. Windows系统 WM_QUIT 消息 ③ PostQuitMessage (0) 应用程序的 WM_DESTROY 消息 消息队列 ① WM_DESTROY 消息的 处理过程 WM_QUIT 消息 GetMessage ( ) ⑤ ④ WinMain ( ) 应用程序 消息 ⑥ 循环 退出消息循环 结束应用程序 WndProc ( ) case 1 case 2 ... ② case WM_DESTROY Default

  22. 结构化异常处理 • Windows在系统底层提供了一种称为结构化异常处理SEH的系统机制。利用SEH可以把程序主要的工作同错误处理分离开来,这样的分离,可以使程序员集中精力关注程序要完成的任务,而将可能发生的错误放在后面处理 • 异常是在应用程序的正常执行过程中发生的不正常事件。CPU引发的异常称为硬件异常,操作系统和应用程序直接引发的异常,称为软件异常

  23. 结构化异常处理 • SHE是操作系统的一种系统机制,与特定的程序设计语言无关 • 应用程序要利用系统提供的SHE机制,则必须借助于特定程序设计语言的相关语法 • 因此,SEH不但涉及操作系统,而且与编译器有密切的关系 • 结构化异常处理包括异常处理和终止处理两个方面

  24. 结构化异常处理 • 异常处理 • __try • { • ... //guarded section • } • __except(exception filter) • { • ... //exception handler • }

  25. 结构化异常处理 • 异常处理 • 异常过滤器返回如下三个异常标识符之一 • ECXEPTION_EXECUTE_HANDLER • ECXEPTION_CONTINUE_EXECUTION • ECXEPTION_CONTINUE_SEARCH

  26. 结构化异常处理 • 终止处理 • Windows应用程序在运行时通常要分配资源,使用这些资源,然后释放它们 • 由于异常改变了控制的流程,因此很容易导致无法释放在产生异常的代码块中分配的资源 • 使用终止处理程序可以保证进行这样的清除工作

  27. 结构化异常处理 • 终止处理 • __try • { • ... • } • __finally • { • ... • }

  28. 结构化异常处理 • 终止处理 • 有两种情况可能使受保护段不正常地结束 • 在try块中执行了return、goto、break或continue等控制语句 • 在try块中发生异常

  29. 结构化异常处理 • 软件异常 • 当一个函数执行失败时,习惯上要返回一些特殊的值来,函数的调用者可以检查这些特殊值并采取一种替代的动作 • 如果这个调用者是被另一个调用者调用的函数,那么它还需要将它自己的失败代码返回给它的调用者 • 这种错误代码的逐层传递会使源程序变得非常难于编写和维护 • 采用软件异常则可以解决这些问题

  30. 动态链接库 • 动态链接库DLL是一个可执行程序模块,模块中包含了可以被其他应用程序或其他DLL共享的程序代码和资源

  31. 动态链接库 • 采用DLL的优点: • 当多个进程同时使用同一个DLL时,只要在内存中装入它的一个副本即可,从而可以节省内存; • DLL与调用它的应用程序相分离,因此可以在不修改应用程序的情况下对DLL进行更新; • 只要在调用DLL中的函数时遵循相同的调用规范,那么DLL中的函数就可以被各种编程语言编制的应用程序调用

  32. 动态链接库 • DLL到进程地址空间的映射 • 装入时刻动态链接 DLL 引入库,包含 函数的重定位信息 . obj 经过编译的 文件 链接器 动态链接库 可执行程序 重定位 信息 内存 DLL 调用 中的函数

  33. 动态链接库 • DLL到进程地址空间的映射 • 运行时刻动态链接 • 在运行时刻,通过调用LoadLibrary可以使DLL加载到一个进程的地址空间中 • 为了在运行时刻从DLL中调用一个函数,可以通过调用GetProcAddress获取函数的地址

  34. 2 GB 2 GB 虚拟地址空间 物理内存 DLL 代码 DLL 数据 (共享) DLL 数据 1 (私用进程 ) DLL 数据 1 (私用进程 ) 0 0 1 进程 2 进程 动态链接库 • DLL到进程地址空间的映射

  35. 动态链接库 • DLL的入口点函数 • DLL没有WinMain函数,不含有消息循环,一般也不获取自己的消息,但是它有自己特殊的入口点函数,入口点函数的缺省名为DllMain • 当进程和线程被初始化或终止时,DllMain函数被Windows系统调用 • DllMain要做的主要任务是执行进程级或线程级的初始化和清理工作 • 如果不要求DLL初始化,DllMain可以只是一个虚设函数

  36. 动态链接库 • DLL的创建和使用 • 创建DLL文件需要用到源文件(.C)和头文件(.H)。DLL源文件通常包括入口点函数和供应用程序调用的DLL库函数。头文件中含有DLL要导出的所有函数与变量的说明 • 在应用程序中调用DLL中的函数或访问DLL中的变量时,须告诉编译器要调用的函数或要访问的变量是在DLL中: • __declspec(dllimport) • int Sub(int nPara1, int Para2);

  37. 习题 • Win32子系统与Win32 API的关系是什么? • 什么是事件驱动?Windows应用程序为什么采用事件驱动的程序设计方法,而不是象传统DOS应用程序那样采用过程驱动的程序设计方法? • 与静态链接相比,动态链接有哪些优点?有哪些缺点?

  38. Windows驱动程序模型 • WDM以Windows NT 4.0的内部结构为基础,同时引入了 Windows 9x的即插即用特性,为存在于Windows 98和Windows 2000/XP/2003操作系统中的设备驱动程序提供了一个统一的参考框架 • WDM驱动程序还可以在不修改源代码的情况下经过重新编译后在非Intel平台上运行,因此WDM是一个跨平台的驱动程序模型

  39. IRP 上层过滤器驱动程序 FiDO FDO 功能驱动程序 FiDO 下层过滤器驱动程序 PDO 总线驱动程序 设备和驱动程序的分层 • WDM是一个分层化的驱动程序模型,在这个模型中,驱动程序的层或堆栈一起工作处理I/O请求

  40. 设备和驱动程序的分层 • 总线驱动程序 • 总线驱动程序负责枚举连接在该总线上的所有设备并进行必要处理 • Microsoft为大多数总线如PCI、PnPISA、SCSI以及USB等提供了驱动程序 • 机器中每种类型的总线都有相应的总线驱动程序 • 总线枚举时驱动程序识别其上的设备并为其创建一个物理设备对象

  41. 设备和驱动程序的分层 • 功能驱动程序 • 功能驱动程序是一个设备的主要驱动程序,它知道如何控制设备的主要功能 • 功能驱动程序为它的设备提供操作接口,处理对设备的读/写,并管理设备的电源策略 • 功能驱动程序创建一个功能设备对象FDO放在设备栈中

  42. 设备和驱动程序的分层 • 过滤器驱动程序 • 过滤器驱动程序过滤对每个设备、每一类设备或一条总线的I/O请求 • 过滤器驱动程序是可选择的

  43. IRP的处理 • IRP是驱动程序操作的中心。I/O管理器接收一个I/O请求之后,在把它传递到合适的驱动程序堆栈中的最高层驱动程序之前,分配并初始化一个IRP • 当一个IRP由多个驱动程序处理时,使用多个I/O堆栈单元。每个驱动程序从当前I/O堆栈单元得到它的IRP参数。如果把一个IRP沿当前设备的驱动程序堆栈向下传递,必须使用正确的常数设置下一个堆栈单元

  44. IRP I/O 驱动程序 堆栈单元 1 1 最高 I/O 驱动程序 堆栈单元 2 2 I/O 驱动程序 堆栈单元 3 3 I/O 驱动程序 堆栈单元 4 4 最低 IRP的处理

  45. 用户程序对设备的访问过程 • Windows中对设备的访问分为用户态和核心态两种方式: • 用户态通过调用Win32 API函数如ReadFile、WriteFile等访问设备,它不能直接控制硬件 • 核心态通过发送I/O请求包IRP来运行驱动程序实现对设备的控制

  46. 应用程序 Win32子系统 用户态 I/O系统服务 核心态 IRP 高层驱动程序 I/O管理器 中层驱动程序 低层驱动程序 HAL 用户程序对设备的访问过程

  47. WDM驱动程序的结构 I/O 控制例程 基本驱动程序例程 分发例程 DispatchPnp DriverEntry StartIo DispatchPower AddDevice AdapterControl DispatchWmi OnInterrupt DispatchRead DpcForIsr DispatchWrite 必须的驱动程序例程 StarIo 处理请求队列需要包含 DPC 如果设备产生中断需要包含中断和 例程 DMA AdapterControl 操作需要包含 例程 IRP 可选的 分发例程

  48. WDM驱动程序的结构 • 初始化例程,当I/O管理器把驱动程序加载到操作系统中时,它执行驱动程序的初始化例程 • 添加设备例程,用于支持PnP管理器的操作 • 一系列分发(调度) 例程,调度例程是设备驱动程序提供的主要函数 • 启动I/O例程,驱动程序可以使用启动I/O例程来初始化与设备之间的数据传输

  49. WDM驱动程序的结构 • 中断服务例程(ISR),当一个设备中断时,内核的中断调度程序把控制转交给这个例程。ISR运行在高级的设备中断请求级(IRQL)上,越简单越好,以避免对低优先级中断产生不希望的阻塞 • 中断服务DPC例程,DPC例程执行在ISR执行以后的大部分设备中断处理工作。DPC例程在低于ISR的IRQ的时候执行,从而避免对其他中断产生不希望的阻塞。DPC例程初始化I/O完成并启动关于设备的下一个队列的I/O操作

  50. WDM驱动程序编程实例 • WdmDriver是一个WDM驱动程序,它实现了一个4字节的核心态内存缓冲区,Win32 应用程序可以对该缓冲区进行读写操作 • 由于采用WDM模型,WdmDriver 可以运行在Windows 98 和Windows 2000/XP/2003两个平台上

More Related