浅析句柄的本质
本文讨论句柄的本质,使程序员能够真正熟悉经常使用的句柄的含义。相信通过本文会对句柄有一个确切的认识,能够更好的指导编程开发。
在Windows中,句柄是非常有用的东西。什么是句柄。有很多资料,包括MSDN也讲述了句柄是一个32位或者64位的整数值,是一种数据类型,标志了一个对象,可以通过这个句柄访问对象。看了这样的解释,我不相信你就真的明白了句柄是什么。
在C和C++中,指针是无所不能的,因此也是很危险的。系统的很多东西,如果知道确切地址,通过指针就可以直接修改,从而破坏系统。有了指针,指针中的值就存放了内存地址,就可以直接对内存的数据进行修改。系统的内核的东西,是不允许直接访问的,所有操作都必须通过API函数进行,这样就可以保证系统不会被破坏。但是要访问内核的东西,总得要有一个可以定位的东西,比如说地址,这样才能真正知道要操作内核的哪些东西,因为东西很多,总要区分一下。如果说直接给地址,用指针形式进行定位操作,那就会危及系统,所以微软就不提供这种方法来操作。很自然,就采用了一个代号,给内存的所有东西取个名字,就产生一个代号,通过这个代号,你并不知道它的确切的位置,你就无从直接操作它,就不会带来破坏。这个代号要让访问者知道,就必须存储起来,而访问者在系统中是以进程的形式存在的,所以,这些代号就跟进程相关了。一个进程创建了一个东西,这个东西就会返回一个代号,这个代号就记录到进程的一个表了,这样就可以通过这个代号找到这个东西了。而在这个表中,肯定是有一个映射关系的,也就是,这个代号一定会与这个东西的位置进行关联,以后通过这个代号,在表里就能够找到这个东西的地址,然后再操作这个东西。
说了这么多很不专业的描述,相信你对这个过程大致有印象了。这个代号就是句柄,这个表就是句柄表,这个句柄表就是与进程相关的,而这些东西就是系统中被创建的内存中的内存块。现在相信你对于微软为什么搞出一个句柄有所体会了吧。
句柄的存在,保证了系统的安全,程序员不用通过指针直接操作内存中的东西,将句柄传入API函数,函数在内部会在当前的进程的句柄表中去找这个句柄对应的内存块的地址,以及判断该内存块的访问权限和标志,然后再执行之后的操作。这样一来,如果是非法访问,你对于那块内存面都见不到,更不用说去破坏了。而如果是指针,只要指针指向了那个内存块,你就可以对它任意操作了。
所以说,理解句柄,理解到这个地步,你脑子的很多疑问都会自然的没了,看句柄也会顺眼多了。线程句柄、文件句柄、GDI句柄等等,本质都是一样的。如果你不理解的话,还要以为是好多种数据类型,其实就是一个类型。知道了本质,一切都很自然了。
当然,本文只是大致讨论了一下,要想更加深入的理解,本文是远远不够。但是对于初学者来说,了解到这个,已经很够用了。