对句柄的理解

一、句柄描述

1)通过一个简单的数据拎起一大堆数据,这个简单的数据就叫做句柄,即Handle;
2)指针也是一种句柄,因为用户可以通过它存储的32位地址值,可以访问到背后大量数据,如通过数组指针访问数组,通过对象指针访问对象等;但由于指针存储的是可以操作内存的地址,这是与句柄不一样的地方(句柄只是个编号,不与地址对应,也不是地址);
3)windows系统有许多的内核对象程序,如打开的文件,创建的线程,程序的窗口等等;这些对象占内存空间较大,当需要传递这些对象程序的时候,直接采用拷贝传递将导致效率低下,所以传递他们的首地址是一种选择,但直接传递地址,使得用户可以直接操作和修改对应的内存空间,这是内核不允许的;且操作系统会定期整理内存,如果一些内存整理后地址发生了变化,那传递的地址将失效,甚至通过原来的地址访问到了其他的数据(越界访问);
4)windows操作系统为了解决3中的问题,在每个进程的地址空间设置一个表,用于保存内核对象程序的地址和编号,编号与地址没有规律性的联系,纯粹就是映射而已;
5)在windows中,4中表格的编号就叫做:句柄;它是windows用来标识应用程序而建立使用的对象的唯一整数,系统使用各种各样的句柄标识应用程序实例(窗口,控制,位图等等);

二、在进程和线程的上下文深入理解句柄

1、先来谈谈Handle

Handle本身是一个32位的无符号整数,它用来代表一个内核对象。它并不指向实际的内核对象,用户模式下的程序永远不可能获得一个内核对象的实际地址(一般情况下)。那么Handle的意义何在?它实际上是作为一个索引在一个表中查找对应的内核对象的实际地址。那么这个表在哪里呢?每个进程都有这样的一个表,叫句柄表。该表的第一项就是进程自己的句柄,这也是为什么你调用GetCurrentProcess()总是返回0x7FFFFFFF原因。

简单地说,Handle就是一种用来"间接"代表一个内核对象的整数值。你可以在程序中使用handle来代表你想要操作的内核对象。这里的内核对象包括:事件(Event)、线程、进程、Mutex等等。我们最常见的就是文件句柄(file handle)。

另外要注意的是,Handle仅在其所属的进程中才有意义。将一个进程拥有的handle传给另一个进程没有任何意义,如果非要这么做,则需要使用DuplicateHandle(),在多个进程间传递Handle是另外一个话题了,与这里要讨论的无关。

2、进程ID

首先,进程ID是一个32位无符号整数,每个进程都有这样的一个ID,并且该ID在系统范围内是唯一的。系统使用该ID来唯一确定一个进程。

深入些说,系统可能使用进程ID来计算代表该进程的内核对象的基地址(及EPROCESS结构的基地址),具体的计算公式你可以去问微软的OS开发人员。

3、HINSTANCE

HINSTANCE也是一个32无符号整数,它表示程序加载到内存中的基地址。
4、可参考一下文章
图解句柄

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值