Windows句柄介绍

2024-08-30 02:48
文章标签 windows 介绍 句柄

本文主要是介绍Windows句柄介绍,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.句柄是什么? 
在windows中,句柄是和对象一一对应的32位无符号整数值。对象可以  映射到唯  一的句柄,句柄也可以映射到唯一的对象。 
2.为什么我们需要句柄? 
更准确地说,是windows需要句柄。windows需要向程序员提供必要地  编程接口  ,在这些接口中,允许程序员访问、创建和销毁对象。但是,出于封装地  考虑,wi  ndows并不想向程序员返回指针。指针包含了太多的信息。首先指针给出  了对象存储  的确切位置;其次,要操作一个指针,程序员必须知道指针所指对象的内  部结构特  征,也即,windows必须向程序员暴露相应的数据结构,而这些数据结构也  许是操作  系统想向程序员隐藏的。  如果说COM技术向用户隐藏了数据,只暴露了接口并只允许按接口定  义的方法操  作数据的话,句柄这种方式则允许你按自己的方式直接操作数据,但  windows又不向  你直接暴露数据。直接操作数据是程序员需要的,不暴露数据是windows所  需要的,  句柄封装方式实现了各取所需。 
3.句柄如何与对象映射? 
封装背后,必须有一个地方可以实现解码,以实现句柄和对象的相互  转换。在  windows中,存在两种映射方式: 
a. 全等映射。也即,句柄本身就是一个指针。映射在这里只是类型转  换而已。  这种情况有,进程实例句柄或模块句柄,以及资源句柄等等。 
b. 基于表格的映射。这是对象指针与句柄之间最普通的映射机制。操  作系统创  建表格,并保存所有要考虑的对象。需要创建新对象时,要先在表格中找  到空入口  ,然后把表示对象的数据添入其中。当对象被删除时,它的数据成员和其  在表中的  入口被释放。 
4.句柄的定义和实现 
我们以GDI对象为例进行讨论。创建了GDI对象,就会得到该对象的句  柄。句柄  的对象可能是HBRUSH、HPEN、HFONT或HDC中的一种,这依赖于你创  建 的GDI对象类  型。但是最普通的GDI对象类型是HGDIOBJ。HGDIOBJ被定义成空指针。  HPEN的实际编译类型定义随编译时间宏STRICT的不同而不同。如果  STRCIT已经  被定义了,HPEN是这样的: 
struct HPEN__ {int unused}; 
typedef struct HPEN__* HPEN; 
如果STRICT没有定义,HPEN是这样定义的: 
typedef void *HANDLE; 
typedef HANDLE HPEN; 
上面这段代码是一个注重细节的程序员最接近句柄的地方,因此我们重  点分析  一下。这里有一点点技巧。如果定义了STRICT宏,HPEN是指向有单个未  使用字段的  结构的指针,否则HPEN是空指针。C/C++编译器允许把任何类型的指针作  为空指什传  递,反之则不可以。两个不同类型的非空指针是互不兼容的。在STRICT版  本中,编  译对GDI对象句柄的不正确混用将给出警告,对于非GDI句柄,如HWND、 
HMENU的不正  确混用也会给出警告,从而使程序在编译器得到更STRICT的检查。  接下来的分析可能不那么令你感兴趣,但它更深刻地揭示了句柄。对  GDI句柄来  说,尽管windows头文件把它定义成指针,但如果你仔细检查这些句柄的  值,它根本  就不像指针,这也是为什么我说它只是一个32位无符整数值的原因。对句  柄就是指  针的情况,这句话也仍然适用。让我们随意地生成一些句柄,比如你用  GetStockOb  ject()以得到一些句柄,你会发现,它们的值总在区间0x01900011到  0xba040389。  前者指向用户区中的未分配的无效区域,后者指向内核地址空间。另外你 
可能发现  ,两个句柄之间的值可能只差数值1,这也说明GDI句柄不是指针。  和多数人想象的不一样,句柄也不是一个单纯的索引值。对GDI对象 
句柄来说, GDI句柄由8位 、1位堆对象标记(表明对象是否创建在堆中)、7位对象  类型信息和  高4位为0的16位索引组成,如图: 
/// 
3 3 2 2 2 2 2 2 2 2 2 2 1 1 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 
1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 9 8 7 6 5 4 3 2 1 0 
| 8 位引用计数 |堆 | 对象类型7 | 16位索引 |  标  记 
/// 
(格式问题,不好显示) 
在这里你可以看到,对GDI来说,它只使用了16位作为索引。这意味着一  个进程最多只  可以创建小于64K个句柄,实际上受其他一些限制,整个windwos系统中大  概可以容纳约  16384(0x4000)个GDI对象。 

二: 
所谓句柄实际上是一个数据,是一个Long (整长型)的数据。 
句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。 

从上面的定义中的我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的,它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名字和你一样的人。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应的对象。 

如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢? 

为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。 

句柄地址(稳定)→记载着对象在内存中的地址————→对象在内存中的地址(不稳定)→实际对象 

本质:WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的,相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。 

但是必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电影院售给我们的门票总是不同的一个座位是一样的道理。

这篇关于Windows句柄介绍的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1119592

相关文章

Python进阶之Excel基本操作介绍

《Python进阶之Excel基本操作介绍》在现实中,很多工作都需要与数据打交道,Excel作为常用的数据处理工具,一直备受人们的青睐,本文主要为大家介绍了一些Python中Excel的基本操作,希望... 目录概述写入使用 xlwt使用 XlsxWriter读取修改概述在现实中,很多工作都需要与数据打交

java脚本使用不同版本jdk的说明介绍

《java脚本使用不同版本jdk的说明介绍》本文介绍了在Java中执行JavaScript脚本的几种方式,包括使用ScriptEngine、Nashorn和GraalVM,ScriptEngine适用... 目录Java脚本使用不同版本jdk的说明1.使用ScriptEngine执行javascript2.

windows系统下shutdown重启关机命令超详细教程

《windows系统下shutdown重启关机命令超详细教程》shutdown命令是一个强大的工具,允许你通过命令行快速完成关机、重启或注销操作,本文将为你详细解析shutdown命令的使用方法,并提... 目录一、shutdown 命令简介二、shutdown 命令的基本用法三、远程关机与重启四、实际应用

Python实现NLP的完整流程介绍

《Python实现NLP的完整流程介绍》这篇文章主要为大家详细介绍了Python实现NLP的完整流程,文中的示例代码讲解详细,具有一定的借鉴价值,感兴趣的小伙伴可以跟随小编一起学习一下... 目录1. 编程安装和导入必要的库2. 文本数据准备3. 文本预处理3.1 小写化3.2 分词(Tokenizatio

Windows自动化Python pyautogui RPA操作实现

《Windows自动化PythonpyautoguiRPA操作实现》本文详细介绍了使用Python的pyautogui库进行Windows自动化操作的实现方法,文中通过示例代码介绍的非常详细,对大... 目录依赖包睡眠:鼠标事件:杀死进程:获取所有窗口的名称:显示窗口:根据图片找元素:输入文字:打开应用:依

javafx 如何将项目打包为 Windows 的可执行文件exe

《javafx如何将项目打包为Windows的可执行文件exe》文章介绍了三种将JavaFX项目打包为.exe文件的方法:方法1使用jpackage(适用于JDK14及以上版本),方法2使用La... 目录方法 1:使用 jpackage(适用于 JDK 14 及更高版本)方法 2:使用 Launch4j(

windows端python版本管理工具pyenv-win安装使用

《windows端python版本管理工具pyenv-win安装使用》:本文主要介绍如何通过git方式下载和配置pyenv-win,包括下载、克隆仓库、配置环境变量等步骤,同时还详细介绍了如何使用... 目录pyenv-win 下载配置环境变量使用 pyenv-win 管理 python 版本一、安装 和

Python使用pysmb库访问Windows共享文件夹的详细教程

《Python使用pysmb库访问Windows共享文件夹的详细教程》本教程旨在帮助您使用pysmb库,通过SMB(ServerMessageBlock)协议,轻松连接到Windows共享文件夹,并列... 目录前置条件步骤一:导入必要的模块步骤二:配置连接参数步骤三:实例化SMB连接对象并尝试连接步骤四:

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

水位雨量在线监测系统概述及应用介绍

在当今社会,随着科技的飞速发展,各种智能监测系统已成为保障公共安全、促进资源管理和环境保护的重要工具。其中,水位雨量在线监测系统作为自然灾害预警、水资源管理及水利工程运行的关键技术,其重要性不言而喻。 一、水位雨量在线监测系统的基本原理 水位雨量在线监测系统主要由数据采集单元、数据传输网络、数据处理中心及用户终端四大部分构成,形成了一个完整的闭环系统。 数据采集单元:这是系统的“眼睛”,