依赖于一个Windows句柄的类型是一个指针ok? [英] Is relying on the type of a Windows handle being a pointer ok?

查看:137
本文介绍了依赖于一个Windows句柄的类型是一个指针ok?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Windows句柄有时很烦人,记住清理后(做GDI与创建的笔和画笔是一个很好的例子)。 RAII解决方案是伟大的,但是它真的是伟大的一个完整的(规则五)RAII类为每个不同类型的句柄?当然不是!最好的我可以看到一个完整的通用RAII类与其他类只是定义应该做什么时,应该清理手柄,以及其他句柄的特定方面。

Windows handles are sometimes annoying to remember to clean up after (doing GDI with created pens and brushes is a great example). An RAII solution is great, but is it really that great making one full (Rule of Five) RAII class for each different type of handle? Of course not! The best I can see would be one full generic RAII class with other classes just defining what to do when the handle should be cleaned up, as well as other handle-specific aspects.

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

For example, a very simple module class could be defined like this (just an example):

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

private:
    Handle<HMODULE> handle_;
};

这一切都很好,dandy,没有析构函数或任何东西。当然,虽然,能够写 Handle 类不需要析构函数或任何东西也很好。为什么不使用现有的RAII技术?一个想法是使用一个聪明的指针 void ,但是不会工作。下面是在正常情况下实际声明句柄的方法:

That's all fine and dandy, and no destructor or anything is needed. Of course, though, being able to write the Handle class to not need a destructor or anything as well would be nice, too. Why not use existing RAII techniques? One idea would be to use a smart pointer to a void, but that won't work. Here's how the handles are actually declared under normal circumstances:

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

它实际上区别了句柄类型,这是好的,使用智能指针 void 不可能。如果,相反,因为句柄,通过定义,指针,类型可以提取?

It actually differentiates between handle types, which is good, but it makes using a smart pointer to void impossible. What if, instead, since handles are, by definitions, pointers, the type could be extracted?

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

My question is whether the following is a safe assumption to make. It uses a handle to a desktop, which must be closed. Barring the differences between shared and unique pointers (e.g., FreeLibrary has its own reference counting semantics), is assuming the handle is a pointer and making a smart pointer to whatever it's pointing to okay, or should I not use smart pointers and make Handle implement the RAII aspects itself?

#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内核部分(或者有时,可能是由内核代码分配的用户端对象或该主题的某些变体)内部对象的指针。

I believe all Windows pointers are technically pointers to internal objects inside the Windows kernel part of the system (or sometimes, possibly, to user-side objects allocated by the kernel code, or some variation on that theme).

我远远不能相信你应该把它们当作指针。它们只是纯技术角度的指针。他们不再是指针比C风格FILE *是一个指针。我不认为你会建议使用 shared_ptr< FILE *> 来处理以后关闭文件。

I'm far from convinced that you should TREAT them as pointers tho'. They are only pointers in a purely technical perspective. They are no more "pointers" than C style "FILE *" is a pointer. I don't think you would suggest the use of shared_ptr<FILE*> to deal with closing files later on.

将句柄包含在某些东西中,以后清理它是一个好主意,但我不认为使用智能指针解决方案是正确的解决方案。使用知道如何关闭句柄的模板化系统将是理想的。

Wrapping a handle into something that cleans it up later is by all means a good idea, but I don't think using smart pointer solutions is the right solution. Using a templated system which knows how to close the handle would be the ideal.

我想你也需要处理我想把这个句柄从这里传递到别的地方。你有一个函数以某种方式获取资源,并且它返回那些资源的句柄 - 你返回一个已经包装的对象,如果是,该副本如何工作?

I suppose you also would need to deal with "I want to pass this handle from here to somewhere else" in some good way that works for all involved - e.g. you have a function that fetches resources in some way, and it returns handles to those resources - do you return an already wrapped object, and if so, how does the copy work?

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

What if you need to save a copy of a handle before using another one (e.g. save current pen, then set a custom one, then restore)?

这篇关于依赖于一个Windows句柄的类型是一个指针ok?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆