系统相关
首页 > 系统相关> > c – 依赖于Windows句柄的类型是指针吗?

c – 依赖于Windows句柄的类型是指针吗?

作者:互联网

Windows句柄有时很难记住清理后(使用创建的笔和笔刷进行GDI是一个很好的例子). RAII解决方案很棒,但是为每种不同类型的句柄制作一个完整的(五个规则)RAII类真的很棒吗?当然不是!我能看到的最好的是一个完整的通用RAII类,其他类只是定义在清理句柄时要做什么,以及其他特定于句柄的方面.

例如,可以像这样定义一个非常简单的模块类(只是一个例子):

struct Module {
    Module() : handle_{nullptr} {}
    Module(HMODULE hm) : handle_{hm, [](HMODULE h){FreeLibrary(h);}} {}
    operator HMODULE() const {return handle_.get();}

private:
    Handle<HMODULE> handle_;
};

这一切都很好,花花公子,不需要任何析构函数或任何东西.当然,能够编写Handle类不需要析构函数或其他任何东西也会很好.为什么不使用现有的RAII技术?一个想法是使用指向空白的智能指针,但这不起作用.以下是在正常情况下实际声明句柄的方式:

#define DECLARE_HANDLE(n) typedef struct n##__{int i;}*n
DECLARE_HANDLE(HACCEL);
DECLARE_HANDLE(HBITMAP);
DECLARE_HANDLE(HBRUSH);
...

它实际上区分了句柄类型,这很好,但它使得使用智能指针无法实现.相反,如果因为句柄,根据定义,指针可以提取类型呢?

我的问题是以下是否是一个安全的假设.它使用桌面的句柄,必须关闭桌面.除了共享和唯一指针之间的差异(例如,FreeLibrary有自己的引用计数语义),假设句柄是一个指针,并指向它指向的任何东西的智能指针,或者我应该不使用智能指针并使Handle实现RAII方面本身?

#include <memory>
#include <type_traits>
#include <utility>
#include <windows.h>

int main() {
    using underlying_type = std::common_type<decltype(*std::declval<HDESK>())>::type;
    std::shared_ptr<underlying_type> ptr{nullptr, [](HDESK desk){CloseDesktop(desk);}};
}

解决方法:

我相信所有Windows指针都是技术上指向系统Windows内核部分内部对象的指针(或者有时可能指向内核代码分配的用户端对象,或者该主题的一些变体).

我不相信你应该把它们作为指针来对待它们.它们只是纯技术角度的指针.它们不再是“指针”而是C风格“FILE *”是一个指针.我认为您不会建议使用shared_ptr< FILE *>以后处理关闭文件.

将把手包装成稍后清理它的东西绝对是一个好主意,但我不认为使用智能指针解决方案是正确的解决方案.使用知道如何关闭手柄的模板化系统将是理想的选择.

我想你也需要以一种适用于所有参与者的好方式来处理“我想把这个句柄从这里传递到其他地方” – 例如你有一个以某种方式获取资源的函数,它返回那些资源的句柄 – 你是否返回已经包装的对象,如果是,那么复制如何工作?

如果您需要在使用另一个句柄之前保存句柄副本(例如保存当前笔,然后设置自定义笔,然后还原),该怎么办?

标签:handle,raii,c,c11,windows
来源: https://codeday.me/bug/20190825/1721797.html