你了解句柄吗

femalelover 2006-01-01 10:30:51
我觉得自己对于指针理解比较透彻了,但关于句柄的理解,就容易犯理解成指针的错误.
一般说:句柄是资源(或项目)的唯一标识.
俺觉得这其实说得很不明白的,现在我想问的是句柄到底是怎么标识资源的:
1,句柄在32位机上是32位整型吗?
2,当HANDLE handle;声明句柄时,handle是它的标识符吗?如int a;则a就是标识符.
3,既然句柄是一个整型值,那么,它在内存的什么位置呢?栈上吗?
4,句柄是通过在它所占内存中记录对象在内存中的首地址来"标识"对象的吗?如果是,那与指针在这方面就完全一样了.

可能有点玄,大家谈论下吧.
...全文
582 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
two_ears 2006-01-04
  • 打赏
  • 举报
回复
并不是要稀里糊涂地用,而是句柄就是一种封装,它的值并没有文档说明和以前的数据类型有什么关联,一点肯定,说它是指针是不对的,句柄就是句柄,为什么能接受int*这种类型,就不能接受handle这种类型,知道它现在占用32位就对了。
wanguodu 2006-01-03
  • 打赏
  • 举报
回复
怎么又有人问到这个问题了,看看下面的说法够不够清楚:

1、句柄在C语言里(尤其是WIN32 API)常用在为上层提供多实例库函数服务的模块中,主要目的是对上层屏蔽实现细节。句柄对用户来说一般就是一个void *类型的指针(或一个WORD32),而在库函数实现里则把它转换为保存诸如实例状态等信息的数据结构指针。在这种库提供的服务中,一般都要求用户先调用一个open函数以创建一个实例,指向该实例的void *指针返回给用户,此后用户可调用该库中其他函数对该实例进行操作,这些函数中第一个参数为那个open返回的句柄,最后有一个close函数用于放弃对实例的使用,释放相关资源。
2、对于提供服务的库模块来说,其句柄的内存分配要求要么是静态定义要么是动态分配的,总之必须是具有全局生存期的。之所以这样要求是因为不止一个函数要使用它,如果分配在栈里,也即将指向的实例定义为局部变量,则后续函数将访问以前栈中数据,会造成未定义的结果。
3、对于用户来说,句柄的存储分配没有上述要求。譬如,如果你只会在一个函数中调用该库中的函数,那个返回的句柄完全可以定义为局部变量。
shenmea00000 2006-01-03
  • 打赏
  • 举报
回复
有收获啊,不错~~~~
femalelover 2006-01-02
  • 打赏
  • 举报
回复
俺是楼主.
看来大家都是在稀里糊涂地用句柄呀,不管它是什么样的,反正能用就行.
俺提的几个问题,多有针对性呀.呵呵
sankt 2006-01-02
  • 打赏
  • 举报
回复
对句柄的认识
之前在编写MFC程序的时候,有时会碰到句柄这一概念,由于对它一直不是很重视,所以并没有主动去了解它.随着不断深入学习MFC,特别是看完候先生的<<深入浅出MFC>>后,对句柄的实质产生了很大的兴趣,于是到处收集资料,现在总结一下.
handle的中文意思主要有多种,一种是作为名词:柄,把柄;一种是作为动词:处理.硬要从中文意思来说的话,这两种中文意思都可以用来勉强解释句柄.例如一个锅的手柄,你只要抓住了它,你就可以很好地操作那个锅,不过很明显你只能通过锅的手柄来做一些诸如炒菜之类的事,你不可能是因为抓住了锅的手柄才能去看电视.不能的物体都会至少有一个属于它的"手柄".在MFC里面,有很多对象,例如对话框,窗口,画笔,显示器,打印机等,每个对象都会产生一个属于它自己的句柄.oh!慢着,似乎还没说清楚句柄的本质,下面再作详细的解说吧.

如果查看各种HANDLE的定义,如HDC,HPEN,HINSTANCE等等,你会发现有这样一个声明:

DECLARE_HANDLE(HDC);

再把DECLARE_HANDLE这个宏展开来看一下:

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

这是什么意思?用HDC替换上面的name来看看,我们就得到了下面的一段代码:

struct HDC__

{

int unused;

};

typedef struct HDC__ *HDC

oh,原来句柄就是一个指向某一结构的指针,这个结构体只有一个成员,它是一个整数(不知为什么MS要把这个成员叫做unused,难道真的没有用吗?).

嗯,我们再看一个HANDLE的定义,在winnt.h头文件中,我们看到了HANDLE的定义:

typedef PVOID HANDEL;

PVOID是什么?再看它的定义:

typedef void *PVOID;

真相出来了,原来HANDLE不过是一个指向void型,即无类型的指针,嗯,目前的指针是32位的吧.其实也不能说HANDLE是一种指针,它只充当一种索引的作用.真的很难解释HANDLE是什么,再往下看看,只能意会吧,呵呵.

知道了HANDLE的本质(一个32位的整数,用16进制表示),再来说说HANDLE的作用.看我前面第二段的例子,你可以了解到为了控制一个物体,你需要找到它的"手柄".HANDLE就是充当win32下各种"物体"的"手柄".事实上,很多windows API都需要一个HANDLE作为输入参数,这是因为API需要和一些你看不见的对象打交道,这些对象是不能被你所移动或修改的,所以不能给你一个指针来对它进行操作.oh,指针的确是个好东西,它所拥有的能力实在太强大了,但所谓能力越大,责任越大,使用指针的时候千万要小心,不然会造成毁灭性的错误.所以,为了安全,还是给你一个HANDLE吧,通过这个HANDLE,你就可以对那些对象进行一些处理.HANDLE在这里充当什么角色呢?应该算是一个中间人吧,HANDLE是固定的,它不会变,但是对象的地址会变,当对象在内存中的位置发生改变后,我们不能通过之前的对象指针找到对象,怎么办呢?嗯,这时候HANDLE的用处就出来了,HANDLE就是用来记录对象的最新地址的.有点明白了吧?换一种说法吧,嗯,其实就是你知道HANDLE在哪里,但你不知道对象在哪里,而HANDLE知道对象在哪里,所以,只要你知道了HANDLE在哪里,你就能找到对象(尽管你还是不知那个对象住在内存的哪个地方,不过找到它就行了,不是吗?).嗯,是不是有点像索引的作用呢?为什么不给我们知道对象在内存中的位置呢?呵呵,操作系统怕你对它进行一些不利的操作啊.反正你通过HANDLE能让对象做它应该做的事,这就足够了.这就是封装吧,MS最喜欢做的事情,呵呵.

其实对于HANDLE的定义,MS公司也不能说得清清楚楚,把HANDLE翻译成句柄也是不太合适的,但有时就是这样,英文能理解的东西,翻译到中文反而就混乱了,所以"句柄"这个名词比较适合初学者,如我.那些有丰富编程经验的人一定不喜欢使用"句柄"这个名词吧,还是用handle这个原版英文单词比较容易理解
two_ears 2006-01-02
  • 打赏
  • 举报
回复
句柄不理解?理解身份证号码吗,它是怎么标识你自己的?
你活得的指针也一样,用的是windows吗?
虚地址,也不是真正的物理内存的位置,至于怎么管理,如果需要你知道,那还要句柄干什么?
句柄可以标识内核对象,内存,或者是别的什么东西。
把它看成一种封装吧。
非要知道句柄是什么东西,只能说它就是一个类型为HANDLE的值,存储在哪,那和其他类型的变量是一样的。
fiftymetre 2006-01-02
  • 打赏
  • 举报
回复
句柄就像是一把扇子你抓住了扇子的柄也就可以摇动这把扇子了,呵呵。自己理解吧
husl 2006-01-02
  • 打赏
  • 举报
回复
4,句柄是通过在它所占内存中记录对象在内存中的首地址来"标识"对象的吗?如果是,那与指针在这方面就完全一样了
---- 对象在内存中 谁要标识它 都得要内存地址
即使用的同样是首地址 和指针也不是一样的 它这个首地址不像指针那样对我们透明 是经过封装的
femalelover 2006-01-02
  • 打赏
  • 举报
回复
上午比较忙,没来得及仔细看楼上黄景天(名字很帅)的回复.
觉得说得蛮好,比较本质了.句柄就是一个比较特殊的指针,但它的操作能力(或说权限吧)比一般指针差很远,而它的最大优点就是能随时定位资源的地址.
不过有一句我不大同意:
"当对象在内存中的位置发生改变后,我们不能通过之前的对象指针找到对象."
对象在内存中的地址变化之后,指针的记录不会更新吗?依然记录着对象变化之前的地址?
大家再讨论一下吧.不知道怎么样提交FAQ的呢,要不给黄景天的信誉分加一分?
myhearton 2006-01-02
  • 打赏
  • 举报
回复
楼上的可否再说具体一点啊
snowmansh 2006-01-02
  • 打赏
  • 举报
回复
Handle 就是个偏移量(offset)。

每个Process都有个资源表,handle + 表地址 = 一个特定的资源在表中的位置,比如一个文件。

你应该看看,关于windows kernel的书,里面有你问的所有答案。
happydivid 2006-01-02
  • 打赏
  • 举报
回复
学习!
JoyerHuang_悦 2006-01-02
  • 打赏
  • 举报
回复
楼主似乎很明了句柄的样子,于是在下静静听大家的回复。。
cunsh 2006-01-02
  • 打赏
  • 举报
回复
不知道.
mark
我觉得"句柄"这个名字真糟糕. 不知道这个词是谁发明的.
YufengShi 2006-01-02
  • 打赏
  • 举报
回复
楼猪先不要深究句柄怎么代表资源,只要记住通过句柄能够handle资源就行了
至于句柄到底怎么代表资源,那是api的事情,我们用这个句柄就是了
whyglinux 2006-01-01
  • 打赏
  • 举报
回复
可以把句柄理解为数组的下标,通过这个下标能对需要的结构进行定位。但是,无论是数组名(不妨这样称呼)还是结构对于用户来说都是不透明的,只有编译器才知道它们的具体定义。对于用户来说,使用的只是一个数组的下标——句柄,没有必要知道这个句柄代表的信息的具体实现,所以实现了对于具体细节的隐藏,简化了使用。
femalelover 2006-01-01
  • 打赏
  • 举报
回复
第四问最关键了,我没说清楚,重问一遍:
比如一个DC的句柄m_hDC,
如果m_hDC占四个字节内存,它是通过在这一小块内存中记录着DC的地址,
从而达到标识某个特定DC的目的吗?

64,631

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧