【发布时间】:2018-10-09 16:33:19
【问题描述】:
TL;DR
假设我实现了一个类,该类实现了一个返回 HANDLE 的 API。
假设我的班级是 HANDLE 的所有者并负责创建、更新和关闭它。
如何防止我的 API 调用者关闭我的句柄并破坏我的设计?
背景
CreateToolhelp32Snapshot 是一个昂贵的电话,必须明智地使用。
我的解决方案中有很多项目,每个项目都会不小心调用CreateToolhelp32Snapshot。
我想实现一个包装类,它提供对CreateToolhelp32Snapshot 的“智能”访问。
我的班级将是CreateToolhelp32Snapshot 返回的HADNLE 的所有者,并将在需要时更新它(重新调用CreateToolhelp32Snapshot)(尚未完全定义何时需要)。
为简单起见,我们假设我的应用程序是单个进程和线程,并且我的类只有一个实例。
【问题讨论】:
-
如果
HANDLE归您的类实现所有,请不要将其交给客户。如果您需要为客户提供与您的班级交流的方式,请给他们一个您制作的句柄类型,您的班级可以映射到实际的HANDLE,而无需离开您的班级。 -
如果您以正常方式(例如 pimpl)隐藏 HANDLE 的实现,您应该不会遇到很多问题。 HANDLE 不会创建或删除任何内容,您只需 2 个 API 调用即可创建和销毁。但我想我没有得到任何东西。
-
@IInspectable 我的包装类的客户端需要
HANDLE才能使用许多其他 WINAPI。我不想封装使用该句柄的整个 API 系列。 -
您当然可以在将句柄传递给客户端之前调用
DuplicateHandle,并强制客户端关闭此句柄。但是如果他们不关闭它会怎样?如果客户使用无效参数调用您的代码会怎样?如果客户端代码不正确和崩溃过程怎么办?只需将原始句柄传递给客户端,它就不能关闭它。如果客户端代码不正确 - 这不是您的问题。它总是可能不正确并破坏所有 -
也可以作为“解决方案”调用
SetHandleInformation和HANDLE_FLAG_PROTECT_FROM_CLOSE以保护您的句柄不被关闭。最后自己删除这个标志。猜客户也不要尝试这样做))