翻译《The Old New Thing》 - Why are HANDLE return values so inconsistent?

Why are HANDLE return values so inconsistent? - The Old New Thing (microsoft.com)icon-default.png?t=N7T8https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443

Raymond Chen 2004年01月27日


简介

        在处理 Windows 编程中的句柄时,开发者需要面对的一个挑战是不同函数可能返回不同的错误值。这种不一致性源于对16位Windows系统的兼容性考虑,以及随着时间的推移,新函数的添加并没有统一的返回值标准。因此,开发者在编写代码时必须小心谨慎,确保正确处理函数返回的句柄值,避免潜在的错误和资源泄漏。

正文

         

        在查看各种返回句柄(HANDLE)的函数时,你会发现它们的行为并不统一:有些函数在失败时返回 NULL(如 CreateThread),而另一些则返回 INVALID_HANDLE_VALUE(如 CreateFile)。你必须查阅具体函数的文档,以了解它们在失败情况下的返回值。

        这种不一致性的原因,可能正如你所猜测的,是出于历史兼容性的考虑。这些返回值的选择是为了与16位的Windows系统兼容。在16位的Windows中,OpenFile、_lopen 和 _lcreat 等函数在失败时返回 -1,因此32位的 CreateFile 函数为了便于从16位Windows代码迁移,选择返回 INVALID_HANDLE_VALUE。

        此外,由于没有16位的Windows等效函数,CreateThread 或 CreateMutex 等函数则返回 NULL。由于这种不一致性已经成为一种惯例,每当新增函数时,它们是返回 NULL 还是 INVALID_HANDLE_VALUE 都有些随机。

这种不一致性带来了几个后果:

  1. 你必须仔细检查每个函数的返回值。
  2. 如果你编写一个通用的句柄包装类,你需要考虑到两种“非句柄”值的可能性。
  3. 如果你想要预先初始化一个 HANDLE 变量,你必须以与你打算使用的函数兼容的方式进行初始化。例如,以下代码是错误的:

 

HANDLE h = NULL;
if (UseLogFile()) {
    h = CreateFile(...);
}
// 执行其他操作
if (h) {
    Log(h);
}
// 执行其他操作
if (h) {
    CloseHandle(h);
}

        这段代码有两个错误:首先,它错误地检查了 CreateFile 的返回值,代码应该检查 INVALID_HANDLE_VALUE 而不是 NULL。其次,变量 h 的初始化也是错误的。以下是修正后的版本:

HANDLE h = INVALID_HANDLE_VALUE;
if (UseLogFile()) {
    h = CreateFile(...);
}
// 执行其他操作
if (h != INVALID_HANDLE_VALUE) {
    Log(h);
}
// 执行其他操作
if (h != INVALID_HANDLE_VALUE) {
    CloseHandle(h);
}

        4.你必须特别注意 INVALID_HANDLE_VALUE 值:由于巧合,INVALID_HANDLE_VALUE 的数值恰好等于 GetCurrentProcess() 返回的伪句柄。许多内核函数可以接受伪句柄,因此如果你错误地使用了一个失败的 INVALID_HANDLE_VALUE 句柄调用,例如 WaitForSingleObject,你实际上将在自己的进程上等待。这个等待当然不会完成,因为一个进程在退出时会被置为已信号,所以你最终是在等待自己结束。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/570497.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

时间步长问题。tensorflow训练lstm时序模型,输出层实际输出维度和期待维度不一致

设置输出维度为1. Dense(1) 但结果跑出来的输出维度每次都是三维的。 模型设置: 输入x维度(2250,48,2) 输入y 维度(2250,) 和 (2250,1) 但模型预测…

盲人咖啡厅导航:科技之光点亮独立生活新里程

在这个繁华的世界中,咖啡厅不仅是人们社交聚会、休闲阅读的场所,更是无数人心灵栖息的一方天地。然而,对于视障群体而言,独自前往这样的公共场所往往面临重重挑战。幸运的是,一款名为蝙蝠避障专为盲人设计的辅助应用&a…

Day 5 广告管理

Day 5 广告管理 这里会总结构建项目过程中遇到的问题,主要流程,以及一些个人思考!! 学习方法: 1 github源码 文档 官网 2 内容复现 ,实际操作 项目源码同步更新到github 欢迎大家star~ 后期会更新并上传前端项目 创建…

光速记单词-brother开头的单词

1. 思维导图 1.1 brother 1.2 mom 1.3 dad 1.4 man 2. 视频链接

13. Spring AOP(一)思想及使用

1. 什么是Spring AOP AOP的全称是Aspect Oriented Programming,也就是面向切面编程,是一种思想。它是针对OOP(面向对象编程)的一种补充,是对某一类事情的集中处理。比如一个博客网站的登陆验证功能,在用户进行新增、编辑、删除博…

js手写call、bind、apply

目录 call与applyapply bind call和apply和bind有两种实现方式,第一种是隐式绑定,第二种是通过new 无论是通过隐式绑定实现还是通过new实现,核心都是针对this的绑定规则 具体关于this的绑定规则可以看我这一篇博客 this绑定规则 call与apply…

【热议】硕士和读博士洗碗区别的两大理论

::: block-1 “时问桫椤”是一个致力于为本科生到研究生教育阶段提供帮助的不太正式的公众号。我们旨在在大家感到困惑、痛苦或面临困难时伸出援手。通过总结广大研究生的经验,帮助大家尽早适应研究生生活,尽快了解科研的本质。祝一切顺利!—…

【软件测试基础】概述篇(持续更新中)

《 软件测试基础持续更新中》 这一章,是每一名软件测试工程师必须要掌握的常识! 1、软件测试的目的:提高软件质量 和 确保软件满足用户需求。 2、软件测试的概念:使用人工或自动手段来运行或测试某个系统的过程,目的…

品牌差异化战略:Kompas.ai如何打造独特的内容声音

在当今竞争激烈的商业环境中,品牌差异化已成为企业获取市场优势的关键策略。一个鲜明的品牌形象和独特的内容声音不仅能够帮助企业吸引目标客户,还能够在消费者心中建立起独特的地位。本文将深入探讨品牌差异化的重要性,分析Kompas.ai如何帮助…

SL3037内置MOS管 耐压60V降压恒压芯片 降12V或降24V 电路简单

SL3037B是一款内置功率MOSFET的单片降压型开关模式转换器,具有以下特点: 1. 高效率:采用开关式降压技术,仅在需要调节输出电压时才会消耗能量,从而提高了整体的效率。 2. 稳定性好:通过精确的内部电路设计…

数睿通2.0版本升级:探索数据血缘的奥秘

引言 数睿通 2.0 迎来了 4 月份的更新,该版本更新了许多用户期望的数据血缘模块,把原来外链跳转 neo4j 页面改为自研页面,方便后期的二次开发完善,此外,新版本摒弃了 neo4j 的血缘数据存储方案,一来是因为…

接口压力测试 jmeter--进阶篇(三)

一、数据实时监控JMeterGrafanaInfluxdb (mac)性能监控平台搭建JMeterGrafanaInfluxdb 优点: 1.实时 2.美观 3.能够存储和对比 原理: 1.运行jmeter时会吧数据写入到influxdb 2.influxdb实时存储执行的结果 3.grafana链接.influxd…

基于 Flexbox 的纯 CSS 框架:兼容性好、文档丰富 | 开源日报 No.232

jgthms/bulma Stars: 48.3k License: MIT bulma 是基于 Flexbox 的现代 CSS 框架。 基于 Flexbox 技术。提供快速安装方式,支持 NPM、Yarn 和 Bower。仅包含 CSS 文件,没有 JavaScript 部分。兼容性良好,在主流浏览器上运行良好。提供丰富的…

工作中常用的5种加密算法

背景 最近,项目中做了一些安全性要求的整改。而加密是使用过程中常用的手段之一。这里简单的整理下,希望对小伙伴有帮助。 使用场景 加密是一种将原始信息(明文)转换成难以被直接理解的形式(密文)的过程…

信息收集

信息收集 域名的相关知识 域名的技术指的是一个域名由多少级组成,域名的各个级别被“.”分开,简而言之,有多少个点就是几级域名 顶级域名:.com(商)、.edu(教)、.gov(政)、.mil(军) 一级域名:qq.com 二级域名&#xf…

Python--容器、面向对象

一、容器类型(下) 重点学习容器的定义 常用操作的建议 跟着课堂把代码写一遍即可,混个脸熟,后面现用现查 增、删、改、查:重点掌握 查 字符串、元组:只能查,不能改 1.1 字符串str 1.1.1 字符串基本语法 1.1.2 字…

外呼系统出海注意事项

外呼系统在出海过程中需要注意多个方面,以确保系统的有效运行和合规性。以下是一些关键的注意事项: 一、市场调研与目标定位: 在出海前,深入调研目标市场的行业趋势、消费者偏好、文化背景和竞争态势。这有助于企业更好地了解市场…

基于麻雀搜索算法-BP神经网络SSA-BP回归预测

文章目录 效果一览文章概述订阅专栏只能获取一份代码部分源码参考资料效果一览 文章概述 基于麻雀搜索算法-BP神经网络SSA-BP回归预测 订阅专栏只能获取一份代码 部分源码 %------

几种Python处理Excel数据的方法!

第一种方法: 电子表格格式 我们在日常工作中常常见到各种后缀的电子表格,例如最常见的xlsx以及较为常见的csv、xls等格式的表格。同样是电子表格,它们之间有什么区别吗? • xls为Excel早期表格格式。 xls格式是Excel2003版本及…

TDengineGUI无法连接TDengine

可能是TDengineGUI本身的问题,直接下载可执行文件即可 下载地址:Release 1.0.3 ericyangpan/TDengineGUI (github.com) 还有可能是你的6041端口没开注意检查 可在TDengine文件夹下直接执行 systemctl start taosadapter 也可以点击 taosadapter.exe …