句柄的定义及作用

<<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语言中的文件句柄。 

    从上面的两个定义中我们可以看到,句柄实际上是一个标识符,是用来标识对象或者项目的,句柄是一个 32 位的正整数,Microsoft® Windows® 用它来识别窗体或其他对象,例如字体或位图。应用程序几乎总是通过调用一个WINDOWS函数来获得一个句柄,之后其他的WINDOWS函数就可以使用这个句柄,以引用相应的对象。在WINDOWS编程中会用到大量的句柄,比如:HINSTANCE(实例句柄),HBITMAP(位图句柄),HDC(设备描述表句柄),HICON(图标句柄)等等,这当中还有一个通用的句柄HANDLE。 

    一个WINDOWS应用程序可以用不同的方法获得一个特定项的句柄。许多API函数,诸如CreateWindow,GlobalAlloc,OpenFile的返回值都是一个句柄值。另外,WINDOWS也能通过应用程序的引出函数将一个句柄作为参数传送给应用程序,应用程序一旦获得了一个确定项的句柄,便可在WINDOWS环境下的任何地方对这个句柄进行操作。 

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

   “句柄”(handle),handle的本意是把柄,把手的意思。是你与操作系统打交道的东西。举个例子:比如你做了亏心事(我说的是比如,呵呵),不幸让我抓住了把柄,那么我让你做什么你就得做什么,因为你的把柄在我这。我们编程的时候也是这样,比如我们要想操纵一个窗口,那我们就必须“抓住它的把柄”,只有这样,我们才能改变它的属性,改变它的式样,甚至销毁它(狠了点儿)。我们再引用一个通俗一点的例子,比如你考上了大学,入学后,学校(操作系统)会给你一个学生证号。注意,这个号码是学校指定的,你无法自选。有了这个号码(学生证,假设一证多用)就可以享受学校提供的服务:如你就可以去图书馆借书,去食堂吃饭,去教室上课等等。但你不能到食堂里买啤酒,因为学校不允许这种服务。而在计算机中系统提供的服务就是API调用,你有了HANDLE,就可以理直气壮地向系统提出调用API的服务。而指针的权力就大多了,有了指针你可以到处去喝酒,打架,学校(操作系统)管不着,所以句柄和指针的区别在于句柄只能调用系统提供的服务。而句柄虽然是一个能相互区别的号码,但与我们普通的ID号又有区别,普通的ID号是可以由程序员自己定义的,而句柄不行,它是对象生成时系统指定的,是为了区别系统中存在的各个对象,这个句柄不是由程序员赋给的。实际应用中,最常用的就是文件句柄和窗口句柄。例如,窗口句柄的值是一个长整数,每个窗体都用一个句柄来表示。所以句柄是不会重复的,很多的函数都会用到窗体的句柄。 

    到现在,我想你应该对“句柄”这个概念更加理解了吧,说归说,这只是个人的理解,要想真正更深刻的理解,还是要去看一下MSDN的解释,那才是真正的权威 

https://blog.youkuaiyun.com/thiswj/article/details/46476647

https://baike.baidu.com/item/%E5%8F%A5%E6%9F%84/3527587

 
<think>好的,我现在要帮用户查找关于C语言中句柄定义的信息,特别是数据结构和编程方面的内容。用户之前提到了结构体、句柄以及相关头文件的使用,还有他们提供的引用内容涉及到不透明结构体、Windows编程中的HANDLE,以及MATLAB中的函数句柄。我需要整合这些信息,给出一个清晰准确的回答。 首先,我需要明确句柄在C语言中的定义。根据引用[1]和[3],句柄通常用于隐藏内部数据结构,实现封装。比如,不透明结构体通过指针来访问,而用户只能通过提供的函数操作句柄,不能直接修改结构体内部。这样保证了数据的安全性和模块化。 接下来,数据结构方面,用户提到结构体如COORD用于坐标,这可能和游戏或图形编程相关,如引用[2]中的贪吃蛇例子。但用户现在关注的是句柄定义,所以重点应放在不透明结构体上。需要解释如何定义头文件,将结构体声明为不完全类型,这样外部文件只能使用指针而无法访问具体成员。 然后,考虑C编程中的具体实现。引用[1]中的例子,sstruct.h定义结构体,但只被库文件引用,而type.h定义句柄类型和函数接口。这样分离头文件有助于隐藏实现细节。我需要说明这种设计模式的好处,比如降低耦合,提高安全性。 另外,用户提到的Windows编程中的HANDLE(引用[3])是另一种句柄,通常代表系统资源,如文件或窗口。这里需要区分系统级句柄和不透明结构体句柄,虽然两者都是通过句柄抽象资源,但系统句柄可能由操作系统管理,而不透明结构体是用户自定义的。 用户可能还混淆了函数句柄,如引用[4]中的MATLAB例子,但C语言中的句柄通常指资源或结构体的指针,而非函数指针。需要指出这点区别,避免误解。 最后,用户之前的提问涉及_getchar()的头文件,可能对系统资源操作有一定了解,因此需要强调句柄在资源管理中的作用,比如Windows API中的使用。同时,结合用户引用的内容,确保回答覆盖不透明结构体、系统句柄以及实际应用场景,如游戏开发中的坐标处理。 总结回答结构:定义句柄,分点说明不透明结构体和系统句柄,数据结构设计,编程实践,应用场景,注意事项。确保每个部分都有引用支持,并自然添加引用标识。最后生成相关问题,引导用户深入理解。</think>在C语言编程中,**句柄(Handle)** 是一种用于间接访问和管理系统资源或自定义数据结构的抽象标识符,通常通过指针或整型值实现。以下从数据结构、定义方式和应用场景三方面展开说明: --- ### 一、句柄的核心定义与类型 1. **不透明结构体句柄(Opaque Struct Handle)** - **定义**:通过不完全类型(incomplete type)隐藏内部数据结构,仅对外暴露指针类型。例如: ```c // type.h(对外公开) typedef struct Handle* HandlePtr; // 句柄定义为不透明指针[^1] // sstruct.h(库内部使用) struct Handle { int data; void* internal_state; // 隐藏实现细节[^1] }; ``` - **作用**:强制用户通过库提供的函数操作句柄,避免直接访问结构体成员,增强封装性和安全性[^1]。 2. **系统资源句柄(如Windows HANDLE)** - **定义**:在系统编程中,句柄可能是整型值或指针,用于标识文件、窗口等资源: ```c #include <windows.h> HANDLE hFile = CreateFile(...); // 返回系统资源句柄[^3] ``` - **特点**:由操作系统管理生命周期,需通过API函数(如`CloseHandle()`)显式释放[^3]。 --- ### 二、数据结构与句柄设计 1. **不透明结构体的实现模式** - **头文件分离**: - 公开头文件(`type.h`)声明函数接口和句柄类型。 - 私有头文件(`sstruct.h`)定义具体结构体,仅库内部引用[^1]。 - **函数封装**: ```c // type.h HandlePtr create_handle(int init_val); // 创建句柄 void update_data(HandlePtr h, int val); // 操作句柄[^1] ``` 2. **应用场景示例** - **图形编程**:如贪吃蛇游戏中的坐标结构体`COORD`(通过句柄管理位置信息)[^2]: ```c typedef struct _COORD { SHORT X; SHORT Y; } COORD; // 坐标句柄的基础结构[^2] ``` - **资源管理**:Windows API中通过`HANDLE`管理文件、线程等[^3]。 --- ### 三、编程实践与注意事项 1. **内存管理** - 自定义句柄需手动分配/释放内存,避免内存泄漏: ```c HandlePtr h = create_handle(42); // 分配 destroy_handle(h); // 释放[^1] ``` - 系统句柄(如`HANDLE`)需调用对应API释放(如`CloseHandle(hFile)`)。 2. **跨平台兼容性** - 不透明结构体句柄可移植性高,而系统句柄(如Windows `HANDLE`)需平台特定实现。 --- ### 四、句柄与指针的区别 | **特性** | **句柄** | **普通指针** | |----------------|-----------------------------------|----------------------------| | 抽象层级 | 高层抽象(可能封装复杂资源) | 直接内存地址访问 | | 生命周期管理 | 可能由系统/库管理 | 需手动管理 | | 安全性 | 通过封装减少非法操作风险 | 易因误操作导致崩溃/泄漏 | ---
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值