当前位置: 首页 > news >正文

句柄是什么

句柄,handle,英文单词,主要用作名词、动词,作名词时意思是“(门的)把手;柄;(织物等的)手感;(非正式)(人或地方的)称呼;(非正式)赌注总额”,作动词时意思是“(用手)触摸;以手(或前臂)触球;操纵(车辆);(车辆)按特定方式作出反应;处理;对付(某人或某事);有办法应付;经营;接受(或经营)赃物;泰然承受;(车辆容易或难以)驾驶;运送(货物)”。通过门把手才能打开门。通过句柄才能使用winapi操作对象。

句柄(Handle)是一个是用来标识对象或者项目标识符,可以用来描述窗体、文件等,值得注意的是句柄不能是常量。HANDLE:句柄,是Windows用来表示对象的(不是C++的对象),HWND是其中一种,HWND是HANDLE,但HANDLE不只是HWND,HANDLE是一个通用句柄表示,HWND是一个专用表示窗口的句柄。更具体的可查找MSDN。包含在winnt.h头文件中。

句柄只属于Windows,只能由WindowsAPI使用。通过句柄,程序员只能调用系统提供的服务(即API调用),不能像使用指针那样,做其它的事。

Windows之所以要设立句柄,根本上源于内存管理机制的问题,即虚拟地址。简而言之数据的地址需要变动,变动以后就需要有人来记录、管理变动,因此系统用句柄来记载数据地址的变更。在程序设计中,句柄是一种特殊的智能指针,当一个应用程序要引用其他系统(如数据库、操作系统)所管理的内存块或对象时,就要使用句柄。

Windows是一个以虚拟内存为基础的操作系统,很多时候,进程的代码和数据并不全部装入内存,进程的某一段装入内存后,还可能被换出到外存,当再次需要时,再装入内存。两次装入的地址绝大多数情况下是不一样的。也就是说,同一对象在内存中的地址会变化。(对于虚拟内存不是很了解的读者,可以参考有关操作系统方面的书籍)那么,程序怎么才能准确地访问到对象呢?为了解决这个问题,Windows引入了句柄。

系统为每个进程在内存中分配一定的区域,用来存放各个句柄,即一个个32位无符号整型值(32位操作系统中)。每个32位无符号整型值相当于一个指针,指向内存中的另一个区域(我们不妨称之为区域A)。而区域A中存放的正是对象在内存中的地址当对象在内存中的位置发生变化时,区域A的值被更新,变为当前时刻对象在内存中的地址,而在这个过程中,区域A的位置以及对应句柄的值是不发生变化的。这种机制,用一种形象的说法可以表述为:有一个固定的地址(句柄),指向一个固定的位置(区域A),而区域A中的值可以动态地变化,它时刻记录着当前时刻对象在内存中的地址。这样,无论对象的位置在内存中如何变化,只要我们掌握了句柄的值,就可以找到区域A,进而找到该对象。而句柄的值在程序本次运行期间是绝对不变的,我们(即系统)当然可以掌握它。这就是以不变应万变,按图索骥,顺藤摸瓜。

所以,我们可以这样理解Windows句柄:

数值上,是一个32位无符号整型值(32位系统下);逻辑上,相当于指针的指针形象理解上,是Windows中各个对象的一个唯一的、固定不变的ID;作用上,Windows使用句柄来标识诸如窗口、位图、画笔等对象,并通过句柄找到这些对象。

下面,关于句柄,再交代一些关键性细节:

1.所谓“唯一”、“不变”是指在程序的一次运行中。如果本次运行完,关闭程序,再次启动程序运行,那么这次运行中,同一对象的句柄的值和上次运行时比较,一般是不一样的。

其实这理解起来也很自然,所谓“一把归一把,这把是这把,那把是那把,两者不相干”(“把”是形象的说法,就像打牌一样,这里指程序的一次运行)。

2.句柄是对象生成时系统指定的,属性是只读的,程序员不能修改句柄

3.不同的系统中,句柄的大小(字节数)是不同的,可以使用sizeof()来计算句柄的大小。

4.通过句柄,程序员只能调用系统提供的服务(即API调用),不能像使用指针那样,做其它的事。

简介

句柄(handle)是C++程序设计中经常提及的一个术语。它并不是一种具体的、固定不变的数据类型或实体,而是代表了程序设计中的一个广义的概念。句柄一般是指获取另一个对象的方法——一个广义的指针,它的具体形式可能是一个整数、一个对象或就是一个真实的指针,而它的目的就是建立起与被访问对象之间的惟一的联系

在C++中,要访问一个对象,通常可以建立一个指向对象的指针。但是在很多具体的应用中,直接用指针代表对象并不是一个好的解决方案。

对象

句柄是Windows系统中对象或实例的标识,这些对象包括模块、应用程序实例、窗口、控制、位图、GDI对象、资源、文件等。

数据类型

从数据类型上来看,它只是一个16位的无符号整数。应用程序总是通过调用Windows API获得一个句柄,之后其他 Windows函数就可以使用该句柄,以引用和操作相应的内核对象。句柄可以像指针那样置空,那样句柄就没有任何意义,不代表任何内核对象。

使用

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

应该明白的是,句柄是一个标识符,是用来标识对象或者项目的。从数据类型上来看它只是一个16位的无符号整数。应用程序几乎总是通过调用一个Windows函数来获得一个句柄,之后其他的Windows函数就可以使用该句柄,以引用相应的对象。在 Windows编程中会用到大量的句柄。

好处

句柄可以给我们带来如下的好处:

1、我们可以在实现中用尺寸大小固定的(constant-sized)对象来表示尺寸大小不定的(variable-sized)值。

2、我们可以在实现中用运行时绑定(run-time bounding)而不是编译时(compile-timebounding)绑定的方式来处理对象。

3、对于实现的改变通常只会引起一次重新链接,而不是重新编译。

4、我们可以对他人隐藏对象的实现。

发展

在早期的Windows应用程序中,句柄的使用是很频繁的。但随着MFC类库发展,其对Windows内核的封装程度不断提高。这样如果用MFC类库编程的话,就很少会有机会直接对句柄进行操作。但是如果使用 Windows API函数的话,依然需要对句柄进行直接操作 。

在Windows系统中,句柄分为三大类:KernelHandleUserHandle应用程序自定义的HandleKernelHandle实际上是进程内Kernel对象的指针表索引,Kernel对象包括进程、文件、信号。但是MS为了掩盖着一事实,在系统启动时生成了一个所谓Obsfucator的值(其实应该是Obfuscator(混淆器),MicrosoftBugs(R):),生成Handle后将Handle与这个值异或后返回给应用程序,所以看到的Handle都是一些很大而且毫无意义的数字。这些Handle和索引的对象是由KRNL32.DLL和VMM32.VXD共同管理的,所以称之为KernelHandle。 

UserHandle是用来标示窗口、DC等对象的,他们是真实的指针,但指向的并不是对象的开头,有一个偏移量同样,这些对象是由USER32.DLL管理的。第三种Handle不过是应用程序自定义的一些索引之类的东东,具体的意义和应用程序相关。

Windows句柄本质上就是一个指向结构体的指针(define STRICT的情况下)

struct HWND__
{
     int unused;
};

int unused的作用就是使句柄指向一个4字节的内存,以便将来句柄指向对象的地址时能够顺利“转化”。而从始至终,unused从来没有被显式地使用过,所以取名为unused。显然,这里unused的意思是“未被使用的”,而非“没用的”。

相关文章:

  • #define用法
  • c语言预处理命令
  • C++头文件和std命名空间
  • C++输入输出(cin和cout)
  • C++运算符重载的概念和语法
  • GetLastError,ErrLookUp,$err,hr,$eax
  • 字符集和字符编码(Charset Encoding)
  • 进程
  • Windows中的对象
  • Windows对象、句柄与MFC对象
  • C++结构体
  • C++ 指针运算符( 和 *)
  • C++中 引用与取地址的区别
  • C/C++语言中函数参数传递的三种方式(x,*x,x)
  • VC 和 VS 区别
  • 【编码】-360实习笔试编程题(二)-2016.03.29
  • canvas 五子棋游戏
  • Create React App 使用
  • iOS高仿微信项目、阴影圆角渐变色效果、卡片动画、波浪动画、路由框架等源码...
  • Mac 鼠须管 Rime 输入法 安装五笔输入法 教程
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • PAT A1050
  • SpiderData 2019年2月16日 DApp数据排行榜
  • SSH 免密登录
  • Vue 重置组件到初始状态
  • windows下mongoDB的环境配置
  • 对JS继承的一点思考
  • 反思总结然后整装待发
  • 聊聊sentinel的DegradeSlot
  • 猫头鹰的深夜翻译:Java 2D Graphics, 简单的仿射变换
  • 深入浅出webpack学习(1)--核心概念
  • 学习笔记TF060:图像语音结合,看图说话
  • 硬币翻转问题,区间操作
  • ​​​​​​​ubuntu16.04 fastreid训练过程
  • ​Java并发新构件之Exchanger
  • ​queue --- 一个同步的队列类​
  • ​软考-高级-系统架构设计师教程(清华第2版)【第12章 信息系统架构设计理论与实践(P420~465)-思维导图】​
  • #QT(串口助手-界面)
  • (2)nginx 安装、启停
  • (4.10~4.16)
  • (day6) 319. 灯泡开关
  • (zt)基于Facebook和Flash平台的应用架构解析
  • (二)WCF的Binding模型
  • (仿QQ聊天消息列表加载)wp7 listbox 列表项逐一加载的一种实现方式,以及加入渐显动画...
  • (附源码)ssm基于jsp的在线点餐系统 毕业设计 111016
  • (全注解开发)学习Spring-MVC的第三天
  • (一一四)第九章编程练习
  • (转)Android中使用ormlite实现持久化(一)--HelloOrmLite
  • (转载)跟我一起学习VIM - The Life Changing Editor
  • ******之网络***——物理***
  • ***linux下安装xampp,XAMPP目录结构(阿里云安装xampp)
  • *++p:p先自+,然后*p,最终为3 ++*p:先*p,即arr[0]=1,然后再++,最终为2 *p++:值为arr[0],即1,该语句执行完毕后,p指向arr[1]
  • *Django中的Ajax 纯js的书写样式1
  • .NET CF命令行调试器MDbg入门(三) 进程控制
  • .NET 中 GetHashCode 的哈希值有多大概率会相同(哈希碰撞)