C 与 句柄

指针其实也是一种“句柄”,只是由于指针同时拥有更特殊的含义–实实在在地对应内存里的一个地址–所以,通常不把指针说成“句柄”,但指针也有着能从一个32位的值引出一大堆数据的作用,有着与“句柄”相同的功能。

Windows系统中有许多内核对象(这里的对象不完全等价于“面向对象程序设计”一词中的“对象”,虽然实质上还真差不多),比如打开的文件,创建的线程,程序的窗口等。这些重要的对象肯定不是4个字节或8个字节足以完全描述的,它们拥有大量的属性。为了保存这样一个“对象”的状态,往往需要上百甚至上千字节的内存空间,那么怎么在程序间或程序内部的子过程(函数)之间传递这些数据呢?拖着这成百上千的字节拷贝显然会浪费效率。如果传递这些对象的首地址,则存在以下两个缺点:

1)暴露了内核对象本身,使得程序(而不是操作系统内核)也可以任意地修改对象的内部状态,这显然是操作系统内核所不能允许的;

2)操作系统有定期整理内存的责任,如果一些内存整理过一次,对象被搬走,会出现错误。

所以,Windows操作系统就采用进一步的间接:在进程的地址空间中设一张表,表里专门保存一些编号和由这个编号对应一个地址,而由那个地址去引用实际的对象,这个编号跟那个地址在数值上没有任何规律性的联系,纯粹是个映射而已。在Windows系统中,这个编号叫做“句柄”。

Handle在Windows中的含有很广泛,以下关于谈到的Handle除非特别说明,将仅限于进程、线程的上下文中。

  1. Handle

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

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

另外要注意的是,Handle仅在其所属的进程中才有意义。将一个进程拥有的handle传给另一个进程没有任何意义,如果非要这么做,则需要使用DuplicateHandle()。

猜你喜欢

转载自blog.csdn.net/cyy1104/article/details/129612827