*.模块(module)
*.任务(task)
*.实例(instance)
*.文件(file)
*.内存块(block of memory)
*.菜单(menu)
*.控制(control)
*.字体(font)
*.资源(resource),包括图标(icon),光标(cursor),字符串(string)等
*.GDI对象(GDI object),包括位图(bitmap),画刷(brush),元文件 (metafile),
调色板 (palette),画笔(pen),区域(region),以及设备描述表(device context)。
WINDOWS程序中并不是用物理地址来标识一个内存块,文件,任务或动态装入模块的, 相反的,WINDOWS API给这些项目分配确定的句柄,并将句柄返回给应用程序,然后通过句柄来进行操作。 、
句柄是WINDOWS用 来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。
从上面的2个定义中的我们可以看到,句柄是一个标识符,是拿来标识对象或者项目的, 它就象我们的姓名一样,每个人都会有一个,不同的人的姓名不一样,但是,也可能有一个名 字和你一样的人。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他 的WINDOWS函数就可以使用该句柄,以引用相应的对象。WINDOWS编程中会用到大量的 句柄,比如:HINSTA NCE (实例句柄),HBITMA P (位图句柄),HDC (设备描述表句
柄),HICON (图标句柄)等等,这当中还有一个通用的句柄,就是HA NDLE,比如下面的语 句:
HINSTA NCE hInstance ;
可以改成:
HA NDLE hInstance ;
上面的2句语句都是对的。
句柄是一个标识符,是拿来标识对象或者项目的。应用程序几乎总是通过调用一个 WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用该句柄,以引用相应 的对象。
如果想更透彻一点地认识句柄,我可以告诉大家,句柄是一种指向指针的指针。我们知 道,所谓指针是一种内存地址。应用程序启动后,组成这个程序的各对象是住留在内存的。如 果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问对象。但是,如果您真的这样认为,那么您就大错特错了。我们知道Windows是一个以虚拟内存为 基础的操作系统。在这种系统环境下,Windows 内存管理器经常在内存中来回移动对象,依此
来满足各种应用程序的内存需要。对象被移动意味着它的地址变化了。如果地址总是如此变
化,我们该到哪里去找该对象呢?
为了解决这个问题,Windows操作系统为各应用程序腾出一些内存储地址,用来专门登记 各应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。Windows 内存 管理器在移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只 需记住这个句柄地址就可以间接地知道对象具体在内存中的哪个位置。这个地址是在对象装载 (Load)时由系统分配给的,当系统卸载时(Unload)又释放给系统。
注意:
内核对象句柄,是用来标识某个内核对象的一个id
同一个对象的该id对于每个进程是不同的,具体如何实现是ms不公开的算法,以下是一个
近似的,可能的算法:
进程创建时,windows系统为进程构造了一个句柄表
当该进程希望获得一个内核对象句柄或者创建一个内核对象从而获得该对象句柄时 系统会将在句柄表中增加一个表项,表项的内容中存储了指向目标内核对象的指针 同时,系统返回这个表项在句柄表中的索引作为句柄