在Windows程序设计中,句柄是无法精确定义的术语。随便找一个高手,让他
给你讲讲句柄是什么,恐怕他都很难给你一个具体的定义来。
在Windows程序设计中,句柄无所不在,窗口有窗口的句柄HWND,线程和进程也有句柄HANDLE,甚至有人把套接字也称为句柄(我就是这样的)。
句柄在英文中是handle,作为动词讲是处理的意思。简而言之,句柄是处理对象的一个接口,对于程序中所涉及的对象,你可以通过句柄去操作他。你不应该
试图去回答句柄是什么,而应该从务虚的角度去理解他,知道他干什么即可。
有人说,因为handle的定义是void
*,因此他是一个指针。有些熟悉内核的人说这是一个索引。这些说法都是不准确的。需要注意的是,微软并没有精确定义句柄的含义,也许在某个特殊的操作系统
中,他使用了一种内部含义,但是在其他版本中,就不保证这样了。任何对句柄的内在假设都可能导致灾难性的后果。
API是接口,句柄是接口,两者有什么区别?API是一个通用的函数族,他处理所有的对象,而句柄是和某个具体对象相关联的数据结构。只有借助句
柄,API才知道处理哪个对象。句柄是对内核对象的引用。
Kernel object handles are process specific. That is, a process must either create the object or open an existing object to obtain a kernel object handle. The per-process limit on kernel handles is 2^24. However, handles are stored in the paged pool, so the actual number of handles you can create is based on available memory. The number of handles that you can create on 32-bit Windows is significantly lower than 2^24.
Any process can create a new handle to an existing kernel object (even one created by another process), provided that the process knows the name of the object and has security access to the object. Kernel object handles include access rights that indicate the actions that can be granted or denied to a process. An application specifies access rights when it creates an object or obtains an existing object handle. Each type of kernel object supports its own set of access rights. For example, event handles can have set or wait access (or both), file handles can have read or write access (or both), and so on. For more information, see Securable Objects.
In the following illustration, an application creates an event object. The CreateEvent function creates the event object and returns an object handle.
After the event object has been created, the application can use the event handle to set or wait on the event. The handle remains valid until the application closes the handle or terminates.
Most kernel objects support multiple handles to a single object. For example, the application in the preceding illustration could obtain additional event object handles by using the OpenEvent function, as shown in the following illustration.
This method enables an application to have handles with different access rights. For example, Handle 1 might have set and wait access to the event, and Handle 2 might have only wait access.
If another process knows the event name and has security access to the object, it can create its own event object handle by using OpenEvent. The creating application could also duplicate one of its handles into the same process or into another process by using the DuplicateHandle function.
An object remains in memory as long as at least one object handle exists. In the following illustration, the applications use the CloseHandle function to close their event object handles. When there are no event handles, the system removes the object from memory, as shown in the following illustration.
The system manages file objects somewhat differently from other kernel objects. File objects contain the file pointer — the pointer to the next byte to be read or written in a file. Whenever an application creates a new file handle, the system creates a new file object. Therefore, more than one file object can refer to a single file on disk, as shown in the next illustration.
Only through duplication or inheritance can more than one file handle refer to the same file object, as shown in the following illustration.
有些对象有ID。句柄表示特殊的对象,ID也表示某个对象,为什么要两个东西来表示?
首先,句柄不能唯一表示对象。一个对象可以有多个句柄。例如:假设我们用CreateProcess创建一个进程,该进程的第一个线程的句柄会返回给调用
CreateProcess的进程。同时,在新创建的进程中,该线程也会有一个句柄。这样,这个线程就有两个句柄。我们也可以用
DuplicateHandle复制一个句柄,这个句柄和原来句柄是不一样的,但是他们都表示同一个对象。而每个有ID的对象,在系统范围内,ID肯定是
唯一的。
其次,句柄所能实现的功能ID不能实现。毕竟ID只是一个数字,他不能记录很多信息。而句柄可能在其内部结构中记录了很多信息(如权限、有无信号等)。
总之,如果试图解释他到底是什么,学习句柄就会误入歧途。从虚的角度去理解,对于新手是难一点,但是这也许是唯一正确的办法。
那么指针与句柄的区别。恩,知道但不是很确信。
句柄本身就是一个指针,确切地说应该是指向指针的指针。
。我们知道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如简单地理解,似乎我们只要获知这个内存的首地址,那么就可
以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。
我们知道,Windows是一个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各
种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本
身是不变的。
Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来
保存。
这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时
(Unload)又释放给系统。
句柄地址(稳定)→记载着对象在内存中的地址────→对象在内存中的地址(不稳定)→实际对象