究竟什么是句柄(handle)

当初学windows编程的时候搞不清什么是句柄,有人说其实就是个值,有人说它是个特殊的指针。什么值?特殊在哪?没人对我说明白。

 

今天刚看了《windows编程》第三章,由于知识所限,我不敢说看完了就能全面认识什么是句柄,但是,至少明白了它的概念,它在widnows应用程序中所起的作用。我仅仅希望曾经迷茫目前迷茫将来还可能迷茫的初学者们看了下面这些字之后能和我一样有个大概的了解。

 

严谨起见申明下我所指的句柄是windows应用程序的句柄,而且为了说明问题我只用了内核对象句柄作为例子,widnows应用程序用到的当然还有非内核对象句柄,如设备对象句柄。

 

在windows下写程序,多少要用到它的内核对象,比如进程内核对象,互斥内核对象……。这些内核对象就是系统的资源,出于对安全性的考虑,windows不允许在程序里直接访问这些内核对象的内存,而是通过调用它提供给我们的函数返回一个句柄,我们再用这个句柄作为执行特定行为的函数的参数去完成对内核对象的操作,比如创建一个文件映像内核对象,对它读取,写入,关闭。当然,这些函数都需要一个参数,就是我们所要操作的内核对象的句柄。

 

究竟什么是句柄?实质是什么?物理上,我们可以查看HANDLE的定义,它只不过是个几字节大小存储空间。

 

概念上我认为应该这么理解:句柄变量是个几字节大小的存储空间,而要在里面存什么,比如一个表示内存位置的指针值,或者一个整数值,甚至一个浮点数值,都不是我们需要考虑的问题,这些事情是操作系统来完成的。在windows98下或许是个进程的内核对象表的索引值(见下面的文字),在windows2000下或许只是个表示内核对象内存大小的值。在我们需要对内核对象进行操作时,通过传递给上面提到过的那些函数的句柄参数,windows会自己找到内核对象,并执行相应的操作。

 

进程的内核对象表:这里仅仅稍微描述一下,如果你想in-depth理解,那就找本好书好好学习学习。windows98给每个进程维护一个内核对象表(想知道为什么要每个进程维护一张内核对象表,看书!),只要我们在进程里创建或者打开了一个系统中已经存在的内核对象(内核对象可以在进程间共享,但是同一个内核对象的句柄值在不同进程中不一定相同),windows98就会在这个进程的内核对象表里插入一条记录,表明这个进程引用了一个内核对象,这个记录在内核对象表中的位置(索引),比如2,就返回给我们,这就是我们所需要的内核对象在这个进程中的句柄值(我反复提到“这个进程”,是因为句柄值是进程相关的,到现在你应该知道了,不同进程能使用相同的句柄值,但是不要指望它们能绝对指向同一个内核对象)!

 

千万不要先入为主,注意,上面那段字讲的仅仅是widows98操作系统拿什么作为句柄值,并不是每个系统都这么干。假设有个系统,它也打算用内核对象表的方式管理内核对象,但物理上用的是链式存储,也就是说不能直接用下标来索引内核对象在表中的位置,也即,句柄变量不能存储1,2,3……这些索引数了,那要拿什么来作为句柄变量值呢?我想,也许是链表中每个节点的地址吧^_^。

 

其实非内核对象句柄的作用也一样,都是windows防止应用程序滥用资源(这是设计操作系统的目的之一),协调windows与应用程序一起工作的手段。

 

以上纯属我个人理解,如果有误,希望你能通知我,互相学习。

  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
在C#中,句柄Handle)是一个引用或指针,用于表示对托管对象或非托管资源的引用。句柄可以被用于与底层系统交互、管理资源、进行跨 AppDomain 或进程通信等操作。 在C#中,使用句柄可以通过以下方式进行: 1. 托管句柄(Managed Handle):这是对.NET对象的引用,由CLR(Common Language Runtime)进行管理和释放。在C#中,托管句柄的创建和使用是自动的,开发者无需手动管理托管句柄的生命周期。 2. 非托管句柄(Unmanaged Handle):这是对非托管资源(如操作系统提供的资源)的引用。在C#中,可以使用`IntPtr`类型表示非托管句柄。通过调用外部API函数或使用`Marshal`类中的方法,可以获取或创建非托管句柄,并进行相关操作。 以下是使用非托管句柄的一个简单示例: ```csharp using System; using System.Runtime.InteropServices; class Program { // 假设有一个外部API函数,返回一个非托管句柄 [DllImport("mylibrary.dll")] private static extern IntPtr GetHandle(); static void Main() { IntPtr handle = GetHandle(); // 调用一些需要使用句柄的操作 DoSomethingWithHandle(handle); // 释放非托管句柄 ReleaseHandle(handle); } static void DoSomethingWithHandle(IntPtr handle) { // 使用句柄进行一些操作 // ... } static void ReleaseHandle(IntPtr handle) { // 释放句柄的资源 // ... } } ``` 请注意,在使用非托管句柄时,需要确保正确地管理它们的生命周期,包括获取、使用和释放资源。这样可以避免资源泄漏和潜在的安全问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值