arongnet 阅读(1234) 评论(32)
在Windows程序设计中,句柄是无法精确定义的术语。随便找一个高手,让他给你讲讲句柄是什么,恐怕他都很难给你一个具体的定义来。

在Windows程序设计中,句柄无所不在,窗口有窗口的句柄HWND,线程和进程也有句柄HANDLE,甚至有人把套接字也称为句柄(我就是这样的)。

句柄在英文中是handle,作为动词讲是处理的意思。简而言之,句柄是处理对象的一个接口,对于程序中所涉及的对象,你可以通过句柄去操作他。你不应该试图去回答句柄是什么,而应该从务虚的角度去理解他,知道他干什么即可。

有人说,因为handle的定义是void *,因此他是一个指针。有些熟悉内核的人说这是一个索引。这些说法都是不准确的。需要注意的是,微软并没有精确定义句柄的含义,也许在某个特殊的操作系统中,他使用了一种内部含义,但是在其他版本中,就不保证这样了。任何对句柄的内在假设都可能导致灾难性的后果。

API是接口,句柄是接口,两者有什么区别?API是一个通用的函数族,他处理所有的对象,而句柄是和某个具体对象相关联的数据结构。只有借助句柄,API才知道处理哪个对象。

有些对象有ID。句柄表示特殊的对象,ID也表示某个对象,为什么要两个东西来表示?

首先,句柄不能唯一表示对象。一个对象可以有多个句柄。例如:假设我们用CreateProcess创建一个进程,该进程的第一个线程的句柄会返回给调用CreateProcess的进程。同时,在新创建的进程中,该线程也会有一个句柄。这样,这个线程就有两个句柄。我们也可以用DuplicateHandle复制一个句柄,这个句柄和原来句柄是不一样的,但是他们都表示同一个对象。而每个有ID的对象,在系统范围内,ID肯定是唯一的。

其次,句柄所能实现的功能ID不能实现。毕竟ID只是一个数字,他不能记录很多信息。而句柄可能在其内部结构中记录了很多信息(如权限、有无信号等)。

总之,如果试图解释他到底是什么,学习句柄就会误入歧途。从虚的角度去理解,对于新手是难一点,但是这也许是唯一正确的办法。

评论列表
Panic
re: 句柄和ID
个人看法:
句柄定义为void *,只是为了让句柄能够覆盖整个可用内存空间的大小。
一笑
re: 句柄和ID
“句柄”只是个名词儿,中国人翻译的。其实“句柄”压根儿不是句柄,句柄其实就是handle。翻译成句柄了,也就成了句柄。如果你把句柄就理解成句柄,那只说明你不懂英文。如果你懂英文,还是把句柄理解成句柄了,那叫作思维不健全。言而总之,总而言之,你要问我句柄是啥意思,那偶就说:道可道,非常道;名可名,非常名。:)
Coder Jozu
re: 句柄和ID
七猫,怎么走哪贴哪啊???
这个话题很有意思,我也说两句关于句柄的我的见解吧
我觉得句柄如果翻译成把手可能更有直译一点,句柄一般是操作系统避免你直接对某个对象数据结构进行操作而引入的,可以通过句柄来使用某个对象,而不用知道句柄的内容。
而句柄根据编程用户的角度分成两种,user对象和内核对象,从NT开始他们的实现分别由ntoskrnl和Win32k两个系统组件管理,user对象的独立实体称之为句柄,这个句柄值由于都由win32k管理,这些句柄的值就是整个系统唯一的,例如我们可以调用findwindows,返回的窗口句柄就是整个系统唯一的。
而内核对象不一样,内核对象的句柄是和进程相关的,每一个进程数据结构中包含一个叫内核句柄表的东西,这是一个分级表结构,和保护模式的分页寻址机制一样,由三层表组成,每一个最末级的表格的每一项代表一个句柄,调用获得句柄的函数返回的正是这一项在表格中的偏移。一个内核对象可以有多个句柄值指向,当然最后经过句柄表的翻译,最终的结果可以指向同一个内核对象的数据结构。
七猫的垃圾箱
Jozu有联系方法没?有时候碰到没办法的时候你总是浮现在我的脑海中
假如不能随便暴露你的联系方式,请反向连接到QQ:43791167或者hotwangm@hotmail.com
freedk
re: 句柄和ID
哎,大家说来说去不就是靠句柄得到更多的线索罢了....
一笑
to Jozu:
“内核对象的句柄”的“句柄”难道不是handle翻译过来的?:)
Coder Jozu
re: 一笑
所以我觉得老外的english不过如此,要是把handle改称handler就完美了。。。没办法,english好,哈哈
Coder Jozu
to:七猫
我们上网不太方便,可以跟我发邮件吧,你的问题我可不能保证解决。:)邮箱:Jozu@sina.com
ljk
re: 句柄和ID
句柄是一种指向指针的指针。我们知 道,所谓指针是一种内存地址。应用程序启动后,组成这 
个程序的各对象是住留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址 访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道,Windows是一 个以虚拟内存为基础的操作系统。在这种系统环境下,Windows内存管理器经常在内存中来回移动对象,依此来满足各种应用程序的内存需要。对象被移动意味着它的地址变化 了。如果地址总是如此变化,我们该到哪里去找该对象呢?为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门 登记各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows内存管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载(Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。句柄地址(稳定)→记载着对象在内存中的地址→对象在内存中的地址(不稳定)→实际对象。但是,必须注意的是程序每次从新启动,系统不能保证分配给这个程序的句柄还是原来的那个句柄,而且绝大多数情况的确不一样的。假如我们把进入电影院看电影看成 是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和每次电 影院售给我们的门票总是不同的一个座位是一样的道理。 
Diviner
ljk:你说的是虚拟内存和物理内存吧,我想。
rt
同一块虚拟内存有可能不同时间对应不同的物理内存或者页面内存吧。
不要太较真
re: 句柄和ID
只是代表性的命名一下,方便统一大家使用,交流
我只知道 HMODULE 的值其实就是PE的 IMAGEBASE值
肉丝
我也来插两句
我觉得其实翻译成什么也无所谓,平常有谁真真的去理解了Handle这个词的真正含义,只是代名词而以。代表某一对象。
清风雨
不能收藏就跟贴,下次可以复习
没钱买地皮,只能无赖啊!
不能收藏就跟贴,下次可以复习
re: 句柄和ID
不能收藏就跟贴,下次可以复习
liw
re: 句柄和ID
ljk可能是正解了,终于理解了。哈哈
Ferrari
re: 句柄和ID
ljk可能是正解了,终于理解了。哈哈 
David
re: 句柄和ID
只可意会,不可言传。。。
JohnMan
re: 句柄和ID
看来程序员们的表达方式都不是深入浅出的,只有LJK的看明白了
龙凤相随
re: 句柄和ID
那么请问我是不是可以理解为句柄的作用就是在保证多任务多进程的前提下有效率的传递事件?
caikanxp
re: 句柄和ID
ID?你指的是VC的资源ID?还是?
justus
re: 句柄和ID
我不是学vc的,感觉句柄和引用——类型安全的指针一个意思吧
VCbird
re: 句柄和ID
错了,错了,错了很多,句柄应该是UINT才对,一个句柄只可能唯一标识一个对象,而一个ID可以标识多个资源,工具栏、状态栏可以用同一个ID标识。。。
william
re: 句柄和ID
我只想知道句柄和指针的区别。
11
re: 句柄和ID
123ljk可能是正解了,终于理解了。哈哈   

发表评论
切换编辑模式