句柄:句柄是一个32位的整数,实际上是windows在内存中维护的一个对象(窗口等)内存物理地址列表的整数索引

指针:指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据

(在Linux
有相应机制,但没有统一的句柄类型,各种类型的系统资源由各自的类型来标识,由各自的接口操作。)

当把硬盘上的资源调入内存以后,将有一个句柄指向它,但是句柄只能指向一个资源。而且句柄知道所指的内存有多大。还有指针,指针指向地址,它不知道分配的内存有多大。

但是如果你定义一个句柄,然后在VC里面右击鼠标,选择"go to definition of handle”,你会发现它的本质就是一个指针,但是它的作用不同于指针。它和通常意义上的指针是有区别的。句柄借用了指针的思想,有它的逻辑特点,但没 有它的物理功能。句柄是WINDOWS分配给窗口等资源的唯一标识,是一个整数。

一、书上定义:

<<Microsoft Windows 3 Developer''s Workshop>>(Microsoft Press,by Richard Wilton)

在Windows环境中,句柄是用来标识项目的,这些项目包括:模块(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编程短平快>>(南京大学出版社):

句柄是WONDOWS用来标识被应用程序所建立或使用的对象的唯一整数,WINDOWS使用各种各样的句柄标识诸如应用程序实例,窗口,控制,位图,GDI对象等等。WINDOWS句柄有点象C语言中的文件句柄。

二、MFC源代码:

#ifdef STRICT

typedef void *HANDLE;

#define DECLARE_HANDLE(name) struct name##__ { int unused; }; typedef struct name##__ *name

#else

typedef PVOID HANDLE;

#define DECLARE_HANDLE(name) typedef HANDLE name

#endif

DECLARE_HANDLE(HMODULE);

DECLARE_HANDLE(HINSTANCE);

DECLARE_HANDLE(HLOCAL);

DECLARE_HANDLE(HGLOBAL);

DECLARE_HANDLE(HDC);

DECLARE_HANDLE(HRGN);

DECLARE_HANDLE(HWND);

DECLARE_HANDLE(HMENU);

DECLARE_HANDLE(HACCEL);

DECLARE_HANDLE(HTASK);

三、理解:

句柄是一个32位的整数,实际上是windows在内存中维护的一个对象(窗口等)内存物理地址列表的整数索引。因为windows的内存管理经常 会将当前空闲对象的内存释放掉,当需要时访问再重新提交到物理存储,所以对象的物理地址是变化的,不允许程序直接通过物理地址来访问对象。程序将想访问的 对象的句柄传递给系统,系统根据句柄检索自己维护的对象列表就能知道程序想访问的对象及其物理地址了。句柄是一种指向指针的指针。我们知道,所谓指针是一 种内存地址。应用程序启动后,组成这个程序的各个对象是驻留在内存的。如果简单地理解,似乎我们只要获知这个内存的首地址,那么就可以随时用这个地址访问
对象了。但是,如果真这么认为,那么就大错特错了。我们知道windows是一个虚拟内存为基础的操作系统。在这种情况下,windows内存管理器经常 在内存中来回移动对象,以此来满足各种应用程序的内存需要,对象被移动意味着它的地址变化了。如果地址总是如此的变化,我们应该去那里找对象呢?为了解决 这个问题,windows操作系统为各个应用程序腾出一些内存地址,用来专门登记各个应用对象在内存中的地址变化,而这个地址(存储单元的位置)本身是不变的。windows 内存管理器移动对象在内存中的位置后,把对象新的地址告知这个句柄地址来保存。这样我们只需要记住这个句柄地址就可以间接地知道对象具体在内存中哪个位置
了。这个地址是在对象装载(load)时由系统分配的,当系统卸载时又释放给系统。句并地址(稳定)----->记载着对象在内存中的地址 -------->对象在内存中的地址(不稳定)----->实际对象。但是必须注意,程序每次重新启动,系统不保证分配跟这个程序的句柄还 是原来哪个句柄,而绝大多数情况下的确不一样。假如我们把进入电影院看电影看成是一个应用程序的启动运行,那么系统给应用程序分配的句柄总是不一样,这和 每次电影院给我们的门票总是不同的座位是一个道理。

因此,句柄和指针其实是两个截然不同的概念。windows系统用句并标记系统资源,用句并隐藏系统信息。你只需要知道有这个东西,然后去调用它就行了,它是32bit的uint。指针则标记某个物理内存的地址,是不同的概念。

指针对应着一个数据在内存中的地址,得到了指针就可以自由地修改该数据。Windows并不希望一般程序修改其内部数据结构,因为这样太不 安全。所以Windows给每个使用GlobalAlloc等函数声明的内存区域指定一个句柄(本质上仍是一个指针,但不要直接操作它),平时你只是在调 用API函数时利用这个句柄来说明要操作哪段内存。当你需要对某个内存进行直接操作时,可以使用GlobalLock锁住这段内存并获得指针来直接进行操 作。

句柄是指针的“指针”,使用句柄主要是为了利于windows在进程内存地址空间移动分配的内存块,以防止进程的内存空间被撕的四分五裂而存在过多的碎片。

句柄是一些表的索引也就是指向指针的指针。间接的引用对象,windows可以修改对象的"物理"地址和 描述器的值,但是句柄的值是不变的。

句柄可以在获得窗口的时候使用,指针可以进行调用窗口,两个使用的地方不一样.一个括号外,一个括号内.

从窗口指针获取窗口句柄:GetSafeHwnd();

从窗口句柄获取临时窗口指针:FromHandle();

从窗口句柄获取永久窗口指针: FromHandlePermanent();

其实两者被没有关系,实际上是MFC在创建窗口的时候用钩子函数沟住HCBT_CREATEWND消息,

然后通过CWnd::Attach()函数把二者捆绑在一起。

以后就可以用GetSafeHwnd(),FromHandle(),FromHandlePermanent()这三个函数可以互相得到了。

MFC之所以要这样做,主要是为了使原来的SDK面向过程的编程遍成面向对象的编程,所有的MFC的窗口都共用一窗口过程函数,在窗口过程函数里, 通过窗口句柄(HWND)找到窗口对象指针(CWnd *)从而把消息分发到窗口对象中,这样以后就可以在窗口类中实行消息响应编程处理了。

附注:获得窗口句柄三种方法

1.HWND FindWindow(LPCTSTR lpClassName, LPCTSTR lpWindowName)

HWND FindWindowEx(HWND hwndParent, HWND hwndChildAfter,LPCTSTR lpClassName, LPCTSTR lpWindowName)

2.HWND WindowFromPoint(POINT& Point)//获得当前鼠标光标位置的窗口HWND

3.BOOL CALLBACK EnumChildProc(HWND hwnd,LPARAM lParam)

BOOL CALLBACK EnumChildWindows(HWND hWndParent, WNDENUMPROC lpEnumFunc,LPARAM lParam)

BOOL CALLBACK EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam)

BOOL CALLBACK EnumWindowsProc(HWND hwnd, LPARAM lParam)

在Linux中:

1.句柄就是一个标识符,只要获得对象的句柄,我们就可以对对象进行任意的操作。

2.句柄不是指针,操作系统用句柄可以找到一块内存,这个句柄可能是标识符,map的key,也可能是指针,看操作系统怎么处理的了。
fd算是在某种程度上替代句柄吧;
Linux
有相应机制,但没有统一的句柄类型,各种类型的系统资源由各自的类型来标识,由各自的接口操作。

3.http://tech.ddvip.com/2009-06/1244006580122204_11.html
在操作系统层面上,文件操作也有类似于FILE的一个概念,在Linux里,这叫做文件描述符(File
Descriptor),而在Windows里,叫做句柄(Handle)(以下在没有歧义的时候统称为句柄)。用户通过某个函数打开文件以获得句柄,此
后用户操纵文件皆通过该句柄进行。
设计这么一个句柄的原因在于句柄可以防止用户随意读写操作系统内核的文件对象。无论是Linux还是Windows,文件句柄总是和内核的文件对象相关联的,但如何关联细节用户并不可见。内核可以通过句柄来计算出内核里文件对象的地址,但此能力并不对用户开放。
下面举一个实际的例子,在Linux中,值为0、1、2的fd分别代表标准输入、标准输出和标准错误输出。在程序中打开文件得到的fd从3开始增长。
fd具体是什么呢?在内核中,每一个进程都有一个私有的“打开文件表”,这个表是一个指针数组,每一个元素都指向一个内核的打开文件对象。而fd,就是这
个表的下标。当用户打开一个文件时,内核会在内部生成一个打开文件对象,并在这个表里找到一个空项,让这一项指向生成的打开文件对象,并返回这一项的下标
作为fd。由于这个表处于内核,并且用户无法访问到,因此用户即使拥有fd,也无法得到打开文件对象的地址,只能够通过系统提供的函数来操作。
在C语言里,操纵文件的渠道则是FILE结构,不难想象,C语言中的FILE结构必定和fd有一对一的关系,每个FILE结构都会记录自己唯一对应的fd。

句柄 http://zh.wikipedia.org/wiki/%E5%8F%A5%E6%9F%84

在程序设计 中,句柄是一种特殊的智能指针 。当一个应用程序 要引用其他系统(如数据库、操作系统 )所管理的内存 块或对象 时,就要使用句柄。
句柄与普通指针 的区别在于,指针包含的是引用对象 的内存地址 ,而句柄则是由系统所管理的引用标识,该标识可以被系统重新定位到一个内存地址 上。这种间接访问对象 的模式增强了系统对引用对象 的控制。(参见封装 )。
在上世纪80年代的操作系统(如Mac
OS 和Windows )的内存管理 中,句柄被广泛应用。Unix 系统的文件描述符 基本上也属于句柄。和其它桌面环境 一样,Windows
API 大量使用句柄来标识系统中的对象 ,并建立操作系统与用户空间 之间的通信渠道。例如,桌面上的一个窗体由一个HWND 类型的句柄来标识。
如今,内存 容量的增大和虚拟内存 算法使得更简单的指针 愈加受到青睐,而指向另一指针的那类句柄受到冷淡。尽管如此,许多操作系统 仍然把指向私有对象 的指针以及进程传递给客户端 的内部数组 下标称为句柄。

Linux中句柄是什么?相关推荐

  1. Linux中main是如何执行的

    Linux中main是如何执行的 这是一个看似简单的问题,但是要从Linux底层一点点研究问题比较多.找到了一遍研究这个问题的文章,但可能比较老了,还是在x86机器上进行的测试. 原文链接 开始 问题 ...

  2. Linux中的基础IO(二)

    Linux中的基础IO(二) 文章目录 Linux中的基础IO(二) 一.基本接口 二.文件描述符 三.文件描述符的分配规则 四.重定向 五.dup2系统调用 六.minishell 一.基本接口 i ...

  3. cmd中如何查看当前绝对路径_如何查看 Linux 中文件打开情况?

    (给Linux爱好者加星标,提升Linux技能) 作者:守望(本文来自作者投稿,简介见末尾) 前言 我们都知道,在linux下,"一切皆文件",因此有时候查看文件的打开情况,就显得 ...

  4. Linux中使用异步 I/O 大大提高应用程序的性能

    Linux中使用异步 I/O 大大提高应用程序的性能 原文: http://www.ibm.com/developerworks/cn/linux/l-async/ AIO 简介 Linux 异步 I ...

  5. 如何查看linux中文件打开情况

    如何查看linux中文件打开情况 前言 我们都知道,在linux下,"一切皆文件",因此有时候查看文件的打开情况,就显得格外重要,而这里有一个命令能够在这件事上很好的帮助我们-它就 ...

  6. linux中fopen和open的区别,Linux下open与fopen的区别

    int open(const char *path, int access,int mode) path 要打开的文件路径和名称 access 访问模式,宏定义和含义如下: O_RDONLY      ...

  7. linux wait函数头文件_第五十八章、linux中的3种正常结束进程的方式你都了解么...

    在前两章中我们了解了创建进程,这一章我们来了解下,在linux下怎么结束进程. 在linux中,有3种正常结束进程的方法和2种异常终止的方法: 1. 正常结束: a. 在main函数中调用return ...

  8. Linux中select IO复用机制

    函数作用: 系统提供select函数来实现多路复用输入/输出模型.select系统调用是用来让我们的程序监视多个文件句柄的状态变化的.程序会停在select这里等待,直到被监视的文件句柄有一个或多个发 ...

  9. linux 中-ldl和-lpthread 是什么意思?

    在<Using the GNU Compiler Collection>gcc 4.30 中关于-lpthread的描述如下: -pthread Add support for multi ...

  10. linux中脚本扑捉(trap)信号问题

    linux中脚本扑捉(trap)信号问题 扑捉ctrl+c信号: 1 #!/bin/bash 2 trap "trap" 2; 3 function trap() 4 { 5 ec ...

最新文章

  1. 现在无法停止通用卷设备_软化和柔顺有什么区别吗?头发粗硬适合拉直还是烫卷?...
  2. 手把手教你使用 1D 卷积和 LSTM 混合模型做 EEG 信号识别
  3. 计算机伺服系统的作用是,伺服系统简介及其在数控加工中的应用
  4. iOS开发:通过经纬度获得城市、省份等信息
  5. linux malloc命令,减少 curl 中内存分配操作(malloc)
  6. mysql利用binlog删除数据库_MySQL数据库之mysql手动删除BINLOG的方法
  7. 基于JAVA+SpringMVC+Mybatis+MYSQL的英语在线学习系统
  8. 学linux做笔记本,linux学习之笔记本安装CentOS7
  9. 中等职业教育计算机,计算机应用基础:Windows7+Office2010(中等职业教育规划教材)...
  10. C++ - 虚基类、虚函数与纯虚函数
  11. Android Binder机制:编写自己的本地服务
  12. AD5933的直流偏置和量程自动切换问题
  13. iOS学习笔记-018.舒尔特表游戏
  14. 优优聚:一文搞懂美团外卖新业务“拼好饭”
  15. Android中WebView控件支持地理位置定位
  16. noip模拟赛 终末
  17. windows内核开发学习笔记十五:IRP结构
  18. 状态码的含义,以及HTTP中常见的状态码
  19. Selenium:动态页面模拟点击
  20. 信息系统项目管理师---第九章 项目人力资源管理历年考题

热门文章

  1. Java高并发编程详解系列-Volatile关键字
  2. 并发编程之高并发编程的意义、好处和注意事项
  3. ajax里的data的用法,Jquery中ajax方法data参数的用法
  4. VLAN技术详解三(VLAN三种访问模式)
  5. matlab求统计量:均值/中位数/极值/方差和标准差
  6. word打出计算机图形符号,在word插入符号和特殊符号-word技巧-电脑技巧收藏家
  7. 台式电脑主板插线步骤图_电脑主板跳线接法图文教程(安装过程)
  8. C++多线程之_beginthread与_beginthreadex
  9. 3.8 51单片机-M74HC138译码器驱动8位数码管
  10. 计算机英语词汇电子书,计算机英语词汇-打印版.pdf