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

相关文章

在Windows上使用qemu安装ubuntu24.04服务器的详细指南

《在Windows上使用qemu安装ubuntu24.04服务器的详细指南》本文介绍了在Windows上使用QEMU安装Ubuntu24.04的全流程:安装QEMU、准备ISO镜像、创建虚拟磁盘、配置... 目录1. 安装QEMU环境2. 准备Ubuntu 24.04镜像3. 启动QEMU安装Ubuntu4

Windows下C++使用SQLitede的操作过程

《Windows下C++使用SQLitede的操作过程》本文介绍了Windows下C++使用SQLite的安装配置、CppSQLite库封装优势、核心功能(如数据库连接、事务管理)、跨平台支持及性能优... 目录Windows下C++使用SQLite1、安装2、代码示例CppSQLite:C++轻松操作SQ

基于Python实现一个Windows Tree命令工具

《基于Python实现一个WindowsTree命令工具》今天想要在Windows平台的CMD命令终端窗口中使用像Linux下的tree命令,打印一下目录结构层级树,然而还真有tree命令,但是发现... 目录引言实现代码使用说明可用选项示例用法功能特点添加到环境变量方法一:创建批处理文件并添加到PATH1

MybatisPlus service接口功能介绍

《MybatisPlusservice接口功能介绍》:本文主要介绍MybatisPlusservice接口功能介绍,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友... 目录Service接口基本用法进阶用法总结:Lambda方法Service接口基本用法MyBATisP

Windows的CMD窗口如何查看并杀死nginx进程

《Windows的CMD窗口如何查看并杀死nginx进程》:本文主要介绍Windows的CMD窗口如何查看并杀死nginx进程问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地... 目录Windows的CMD窗口查看并杀死nginx进程开启nginx查看nginx进程停止nginx服务

MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)

《MySQL复杂SQL之多表联查/子查询详细介绍(最新整理)》掌握多表联查(INNERJOIN,LEFTJOIN,RIGHTJOIN,FULLJOIN)和子查询(标量、列、行、表子查询、相关/非相关、... 目录第一部分:多表联查 (JOIN Operations)1. 连接的类型 (JOIN Types)

java中BigDecimal里面的subtract函数介绍及实现方法

《java中BigDecimal里面的subtract函数介绍及实现方法》在Java中实现减法操作需要根据数据类型选择不同方法,主要分为数值型减法和字符串减法两种场景,本文给大家介绍java中BigD... 目录Java中BigDecimal里面的subtract函数的意思?一、数值型减法(高精度计算)1.

Pytorch介绍与安装过程

《Pytorch介绍与安装过程》PyTorch因其直观的设计、卓越的灵活性以及强大的动态计算图功能,迅速在学术界和工业界获得了广泛认可,成为当前深度学习研究和开发的主流工具之一,本文给大家介绍Pyto... 目录1、Pytorch介绍1.1、核心理念1.2、核心组件与功能1.3、适用场景与优势总结1.4、优

Windows 系统下 Nginx 的配置步骤详解

《Windows系统下Nginx的配置步骤详解》Nginx是一款功能强大的软件,在互联网领域有广泛应用,简单来说,它就像一个聪明的交通指挥员,能让网站运行得更高效、更稳定,:本文主要介绍W... 目录一、为什么要用 Nginx二、Windows 系统下 Nginx 的配置步骤1. 下载 Nginx2. 解压

windows系统上如何进行maven安装和配置方式

《windows系统上如何进行maven安装和配置方式》:本文主要介绍windows系统上如何进行maven安装和配置方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不... 目录1. Maven 简介2. maven的下载与安装2.1 下载 Maven2.2 Maven安装2.