手柄(Handle )是用于标识对象或项目的标识符,可用于描述表单、文件等。 请注意,句柄不能是常数。 HANDLE :句柄是Windows用来表示对象的,不是c对象。 HWND是其中之一,HWND是HANDLE。 但是,HANDLE不仅仅是HWND。HANDLE是一个通用句柄表示,HWND是一个专用表示窗口的句柄更具体地说,可以搜索MSDN。 包含在winnt.h头文件中。
句柄是Windows专用的,仅在WindowsAPI中可用。 句柄允许程序员只调用系统提供的服务,即API调用,而不能像使用指针那样做其他事情。 Windows设定句柄的理由,从根本上来说是内存管理机制的问题虚拟地址简单地说,数据的地址需要变更,变更后需要有人记录、管理变更,所以系统<!DOCTYPE8 句柄为用句柄来记载数据地址的变更,当一个APP应用程序引用由数据库或其他系统(如操作系统)管理的内存块或对象时,使用句柄。
Windows是一种基于虚拟内存的操作系统,在许多情况下,进程的代码和数据不会全部加载到内存中。 进程特殊的智能指针加载到内存中,然后交换到外部存储器中,并可能在再次需要时加载到内存中。某一段这意味着同一对象在内存中的地址会发生变化。 (不太了解虚拟内存的人,请参阅关于操作系统的书。 )那么,程序如何才能正确访问对象呢? 为了解决这个问题,Windows引入了句柄。
两次装入的地址绝大多数情况下是不一样的是32位无符号整数值。系统为每个进程在内存中分配一定的区域,用来存放各个句柄对象在内存中的位置发生变化时,区域a的值将更新为当前对象在内存中的地址,但在此过程中,区域a的位置和相应句柄的值不会改变。 按照图像的形式,该机制可以表示为每个32位无符号整型值相当于一个指针,指向内存中的另一个区域(我们不妨称之为区域A)。而区域A中存放的正是对象在内存中的地址。。 这样,无论对象在内存中的位置如何变化,只要了解句柄的值,就可以找到区域a并找到该对象。 句柄的值位于程序有一个固定的地址(句柄),指向一个固定的位置(区域A),而区域A中的值可以动态地变化,它时刻记录着当前时刻对象在内存中的地址。中。 当然,我们,也就是系统可以掌握它。 这就是以不变应万变,循图索骥,顺藤摸瓜。
http://www.Sina.com/http://www.Sina.com /
以上为32位无符号整数值(32位系统以下); 从逻辑上讲,指针是Windows中每个对象的唯一、固定的ID。如果将其激活,Windows将使用句柄来识别窗口、位图、画笔等对象,并从句柄中提取对象
说明有关句柄的重要细节。
1 .“唯一”、“不变”是指程序的一次执行中。 完成此运行后,关闭程序并重新开始运行程序时,此运行中同一对象的句柄值与上次运行时相比通常会有所不同。
其实这也自然可以理解。 “一把抓一把,这个,那个,两者没有关系”,就像扑克牌一样,在这里是指程序的一次执行。
2 .句柄在生成对象时由系统指定,属性为只读,程序员无法修改句柄。
3 .句柄的大小(字节数)因系统而异,可以使用(大小)计算句柄的大小。
4 .在句柄中,程序员只能调用系统提供的服务,也就是API调用,而不能像使用指针一样做其他事情。
句柄(handle )是C编程中经常提到的术语。 表示的不是具体的、固定的、不变的数据类型或实体,而是编程中的广义概念。 句柄一般是获得另一个对象的方法——的广义指针,其具体形式可以是整数、对象或真指针,其目的是与被访问对象建立唯一的联系。
在c中,要访问对象,通常需要创建指向该对象的指针。 但是,在许多具体的APP应用中,直接用指针表示对象并不是一个好的解决方案。
句柄是Windows系统中对象或实例的标识符,如模块、APP应用程序实例、窗口、控件、位图、GDI对象、资源或文件。
从数据类型来看,数据类型只是16位无符号整数。 APP应用程序始终通过调用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系统中,句柄分为三大类:KernelHandle、UserHandle和应用程序自定义的Handle。KernelHandle实际上是进程内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的意思是“未被使用的”,而非“没用的”。