为什么 HANDLE 返回值不同?

 

 

如果你注意各种返回 HANDLE 值的函数,你会发现它们有些返回 NULL (如 CreateThread) 而有些则返回 INVALID_HANDLE_VALUE(如 CreateFile)。你不得不查询文档找出每种函数在失败时返回什么。

 

为什么返回值不统一?

 

如你所猜测,是历史原因。

 

这些值是用于兼容16位 Windows。16位函数 OpengFile, _lopen 和 _lcreate 在失败的时候返回-1。因此32位 CreateFile 函数返回 INVALID_HANDLE_VALUE 以便于从 Win16 中移植代码.

 

(基于此,你可以回答下面的问题:为什么我调用 CreateFile 而实际上并不是创建一个文?为什么不调用 OpenFile?答案是:是,OpenFile 是个更好的名字,但这个名字已经被用了。)

 

另一方面,没有与 Win16 等价的 CreateThread 或 CreateMutex,因此它们返回 NULL。

 

因为前已经设定了不统一的返回值,无论什么时候增加一个新函数,就有点难以确定新函数返回 NULL 或者 INVALID_HANDLE_VALUE。

 

这种不统一有几个后果。

第一,当然,你不得不小心地适时检查函数的返回值。

第二,这意味着如果你写一个通用的句柄封装类,你必须留意两个可能的“非句柄”值。

第三,如果你想预先初始化一个句柄变量,你必须初始化它为一个与你将用的值兼容。如,下面的代码是错误的:

 

 

 

代码有两个bug。首先,从 CreateFile 返回值的检查不正确。上面的代码检查 NULL 而不是 INVALID_HANDLE_VALUE。其次,代码初始化 h 变量不正确。下面是正确的版本:

 

 

第四,你必须非常小心地对待 INVALID_HANDLE_VALUE 值:偶然地,INVALID_HANDLE_VALUE 恰好等于 GetCurrentProcess() 返回的伪句柄。许多内核函数接受伪句柄,因此如果你不幸地偶然调用了,那么,WaitForSingleObject 一个 INVALID_HANDLE_VALUE 句柄,而事实上你在等待自已的进程,这个等待,显而易见,决不能因为进程退出时发出信号完成,因此你将等待你自己终止它。

 

原文链接:http://blogs.msdn.com/b/oldnewthing/archive/2004/03/02/82639.aspx

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值