图解说明——究竟什么是Windows句柄

摘要:
为了解决这个问题,Windows引入了一个句柄。因此,我们可以如下理解Windows句柄:数值上,它是一个32位无符号整数值;从逻辑上讲,指针等同于指针;在图像理解方面,它是Windows中每个对象的唯一固定ID;实际上,Windows使用控制柄来标识窗口、位图、笔刷等对象,并通过控制柄查找这些对象。稍后再写:1.到目前为止,让我们在这里简要介绍一下Windows句柄。想要进一步了解Windows句柄的读者,请参阅下一篇文章“源代码分析-深化Windows句柄的本质”。

图解说明——究竟什么是Windows句柄

参考资料:http://blog.csdn.net/newjerryj/article/details/4383701

          http://www.cnblogs.com/yellowyu/archive/2009/06/07/1497910.html

写在前面:

     对于“句柄”,在下一直停留在一知半解的认识层面,近日在下学习Windows编程,决定趁此机会将句柄彻底搞清楚。查阅了一些网络上的资料,发现网络上的讲解大概可以分为两类:一种是以比喻、类比的方式说明,这种方法虽然形象易懂,但并没有从原理上、本质上加以揭示,让人仍然想问“为什么?”、“怎么实现?”。另一种是给出源代码,无可厚非,这当然是最本质的说明了,但这样一来,又显得不够直观,初学者理解起来有一定的难度。鉴于此,在下尽微末之能,结合自己的愚见,在两者之间折中,用图解的方式来将原理呈现出来,做到一目了然。

这里需要说明:

1.这里将句柄所能标识的所有东西(如窗口、文件、画笔等)统称为“对象”。

2.图中一个小横框表示一定大小的内存区域,并不代表一个字节,如标有0X00000AC6的横框表示4个字节。

3.图解的目的是为了直观易懂,所以不一定与源码完全对应,会有一定的简化。

让我们先看图,再解释。

图解说明——究竟什么是Windows句柄第1张

图解说明——究竟什么是Windows句柄第2张

      其中,图1是程序运行到某时刻时的内存快照,图2是程序往后运行到另一时刻时的内存快照。红色部分标出了两次的变化。

简单解释:

      Windows是一个以虚拟内存为基础的操作系统,很多时候,进程的代码和数据并不全部装入内存,进程的某一段装入内存后,还可能被换出到外存,当再次需要时,再装入内存。两次装入的地址绝大多数情况下是不一样的。也就是说,同一对象在内存中的地址会变化。(对于虚拟内存不是很了解的读者,可以参考有关操作系统方面的书籍)那么,程序怎么才能准确地访问到对象呢?为了解决这个问题,Windows引入了句柄。

      系统为每个进程在内存中分配一定的区域,用来存放各个句柄,即一个个32位无符号整型值(32位操作系统中)。每个32位无符号整型值相当于一个指针,指向内存中的另一个区域(我们不妨称之为区域A)。而区域A中存放的正是对象在内存中的地址。当对象在内存中的位置发生变化时,区域A的值被更新,变为当前时刻对象在内存中的地址,而在这个过程中,区域A的位置以及对应句柄的值是不发生变化的。这种机制,用一种形象的说法可以表述为:有一个固定的地址(句柄),指向一个固定的位置(区域A),而区域A中的值可以动态地变化,它时刻记录着当前时刻对象在内存中的地址。这样,无论对象的位置在内存中如何变化,只要我们掌握了句柄的值,就可以找到区域A,进而找到该对象。而句柄的值在程序本次运行期间是绝对不变的,我们(即系统)当然可以掌握它。这就是以不变应万变,按图索骥,顺藤摸瓜。

      所以,我们可以这样理解Windows句柄:

      数值上,是一个32位无符号整型值(32位系统下);逻辑上,相当于指针的指针;形象理解上,是Windows中各个对象的一个唯一的、固定不变的ID;作用上,Windows使用句柄来标识诸如窗口、位图、画笔等对象,并通过句柄找到这些对象。

下面,关于句柄,再交代一些关键性细节:

1.所谓“唯一”、“不变”是指在程序的一次运行中。如果本次运行完,关闭程序,再次启动程序运行,那么这次运行中,同一对象的句柄的值和上次运行时比较,一般是不一样的。

  其实这理解起来也很自然,所谓“一把归一把,这把是这把,那把是那把,两者不相干”(“把”是形象的说法,就像打牌一样,这里指程序的一次运行)。

2.句柄是对象生成时系统指定的,属性是只读的,程序员不能修改句柄。

3.不同的系统中,句柄的大小(字节数)是不同的,可以使用sizeof()来计算句柄的大小。

4.通过句柄,程序员只能调用系统提供的服务(即API调用),不能像使用指针那样,做其它的事。

写在后面:

1.到此为止,有关Windows句柄就简单介绍到这里。需要说明的是,本文是面向初学者的,旨在让读者对句柄有一个完整而清晰的认知,既要避免知其然而不知其所以然的茫然困惑,又要避免深入源码的艰难晦涩。因此,本文并不能做到绝对的直达本质,同时也可能在个别细节上与真实情况稍有出入,但在下认为这并不贻害初学者对句柄的认识。因为对某一知识的认知,从几乎一无所知或是一知半解到“精通”,往往需要更多新知识的补充,短时间内很难达到,在不影响知识的使用的前提下,先把握整体,在逐步深入细节,不失为一个明智的选择。想进一步深入理解Windows句柄的读者,可以看在下的下一篇文章《源码剖析——深入Windows句柄本质》。

2.在下知识有限,理解不深,如有错误纰漏之处,这里再三恳请大家一定要为在下指出。大家的批评指正是在下进步的源泉。

 

免责声明:内容来源于网络,仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇PL/SQL Developer使用《关于系统工程与经济管理体制》-- 钱学森下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

如何在WPF 应用中获取窗体或控件的句柄

窗体: IntPtr hwnd = new WindowInteropHelper(this).Handle; 控件: IntPtr hwnd = ((HwndSource)PresentationSource.FromVisual(uielement)).Handle; 注:该调用不能在多线程里面使用...

CreateFile函数详解

The CreateFile function creates or opens the following objects and returns a handle that can be used to accessthe object: files pipes mailslots communications resources disk devic...

深入浅出Visual C++动态链接库(Dll)编程

文章作者:宋宝华信息来源:天极网原始连接: http://soft.yesky.com/lesson/318/2166818.shtml?412  动态链接库(DLL)是Windows系统的核心,也是COM技术的基础,因此突破动态链接库一直是技术人员的攻坚目标,本期专题将由浅入深的介绍动态链接库的基础慨念、分类、实现和应用。基础慨念1.概论 先来阐述一...

Windows系统中CreateFileMapping实现的共享内存及用法

在32位的Windows系统中,每一个进程都有权访问他自己的4GB(232=4294967296)平面地址空间,没有段,没有选择符,没有near和far指针,没有near和far函数调用,也没有内存模式。 每个进程都有独立的4GB逻辑地址空间,32位的Windows系统允许每一个进程独立访问自己的内存,即独立于其它进程,也即它自己的32位逻辑地址空间。操作...

C#取色器

闲来无事,就写了一个取色器。原理其实很简单,只需要两步, 获取鼠标光标的位置, 获取当前鼠标光标的位置的RGB颜色值。 获取鼠标光标的位置: System.Drawing.Point p = MousePosition; 获取指定坐标的RGB颜色值,这里我们需要用到1个WIN32的API函数:GetPixel。 GetPixel函数的作用是检索坐标点的...

源码剖析——深入Windows句柄本质

参考资料: 1. http://www.codeforge.cn/read/146318/WinDef.h__html windef.h头文件 2. http://www.codeforge.cn/read/146318/WinNT.h__html winnt.h头文件 3. https://msdn.microsoft.com/en-us/library...