繁体   English   中英

程序是否应检查“不应该”的WinAPI函数是否失败,但可能会失败?

[英]Should programs check for failure on WinAPI functions that “shouldn't”, but can, fail?

最近我使用GetWindowDC - > CreateCompatibleDC - > CreateCompatibleBitmap - > SelectObject - > BitBlt - > GetDIBits系列WinAPI函数更新了一些用于截屏的代码。 现在我检查所有那些失败因为他们可以而且有时会失败。 但是我必须通过删除创建的位图,删除创建的直流并释放窗口dc来执行清理。 在我见过的任何例子中 - 即使在MSDN上 - 也没有检查相关函数(DeleteObject,DeleteDC <ReleaseDC)是否失败,大概是因为如果它们被检索/创建好,它们将永远被删除/释放OK。 但是,他们仍然失败。

这只是一个值得注意的例子,因为呼叫完全相邻。 但偶尔还有其他功能可能会失败,但在实践中永远不会。 比如GetCursorPos。 或者仅在传递无效数据时才会失败的函数,例如FileTimeToSytemTime。

那么,检查可能因失败而失败的所有功能是否良好? 或者有些可以不检查? 作为必然结果,当检查这些应该永不失败的失败函数时,什么是正确的? 抛出运行时异常,使用断言,还有什么?

是否测试的问题取决于失败时你会做什么。 一旦清理完成,大多数样品都会退出,因此验证正确的清理是没有用的,程序在任何一种情况下都会退出。

不检查像GetCursorPos这样的东西可能会导致错误,但是根据避免这种情况所需的代码决定了你是否应该检查。 如果检查它会在你的所有电话周围添加3行,那么你可能最好承担风险。 但是,如果你有一个宏设置来处理它,那么添加该宏以防万一。

正在检查FileTimeToSystemTime取决于您传入的内容。 来自系统的文件时间? 可能安全地忽略它。 从用户输入构建的自定义字符串? 可能更好地确保。

是。 你永远不知道承诺的服务什么时候会因为不工作而感到惊讶。 最好报告错误,即使是惊喜。 否则你会发现自己的客户说你的申请不起作用,原因将是一个完全的谜。 您将无法以及时,有效的方式回应您的客户并且您失败了。

如果您将代码组织起来以便始终进行此类检查,那么将下一个检查添加到您调用的下一个API并不困难。

你提到GetCursorPos很有趣,因为当传递的地址大于2Gb时Wow64进程失败了。 它每次都失败了。 该错误已在Windows 7中修复。

所以,是的,我认为即使你不指望错误也要检查错误。

是的,您需要检查,但如果您使用的是C ++,则可以利用RAII并将清理保留到您正在使用的各种资源中。

另一种方法是混杂使用if-else语句,这真的很丑陋且容易出错。

我使用C ++编写WinAPIs的时间越长,PInvoke和C#的编程越小,我就越用这种方式编写代码:

  1. 设计用法以假设它将失败(最终),无论文档似乎暗示什么
  2. 确保知道通过/失败的返回值指示,因为有时0表示通过,反之亦然
  3. 检查是否记录了GetLastError ,并确定该信息可为您的应用提供的值

如果稳健性是一个足够严重的目标,您可能会认为这是一个值得花时间投入,看看您是否可以使用冗余方法进行容错设计,以获得您需要的任何内容。 很多时候使用WinAPI,有多种方法可以获得您正在寻找的特定信息或功能,有时这意味着使用与WinAPI结合使用的其他Windows库/框架。

例如,获取屏幕数据可以使用直接WinAPI来完成,但一种流行的替代方法是使用GDI +,它可以很好地与WinAPI配合使用。

是。 假设您没有检查函数返回的内容,程序在函数失败后继续运行。 接下来发生什么? 你怎么知道你的课程为什么长时间行为不端?

一个非常可靠的解决方案是抛出异常,但这需要您的代码是异常安全的。

是。 如果一个函数可能失败,那么你应该防止它。

对代码中潜在问题进行分类的一种有用方法是潜在的失败原因:

  1. 代码中的无效操作
  2. 客户端代码中的无效操作(调用您的代码,由其他人编写)
  3. 外部依赖项(文件系统,网络连接等)

在情况1中,它足以检测错误而不执行恢复,因为这是一个应该由您修复的错误。

在情况2中,应该将错误通知给客户端代码(例如,通过抛出异常)。

在情况3中,您的代码应尽可能自动恢复,并在必要时通知任何客户端代码。

在情况2和3中,您应该努力确保您的代码恢复到有效状态,例如,您应该尝试提供“强烈的例外保护”等。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM