c++ - 如何在运行时检查 Win32 句柄的 "type"

标签 c++ winapi c++11

我必须在 C++11 中为 HFONT、HWND、HMODULE 等 Win32 句柄编写引用计数包装类。我想使用一个隐式转换为所有句柄类型(都是 void* typedef)的 WinHandle 类。不幸的是,所有句柄都有不同的函数来销毁底层对象,例如 DestroyWindow()、CloseHandle()、DeleteObject() 等等,因此我需要为每个句柄类型使用不同的类来实现适当的销毁函数。 (那将是 47 个类 + 包括用户对象、gdi 对象和内核对象的基类)

那么有没有办法在运行时确定句柄是哪种“类型”或者需要调用哪个函数? (在文档中我只找到了 isWindow() 函数)

我已经考虑过使用 RTTI 或调用所有删除函数,直到其中一个成功为止。 RTTI 将不起作用,因为所有 HANDLE 类型都是 void* 的类型定义,因此是相同的。后者可能有效,但所有句柄都必须是唯一的才能正常工作(没有 GDI 句柄可以与用户句柄或内核句柄具有相同的值)否则它可能会导致错误和内存泄漏

最佳答案

如果您唯一要查找的是引用计数句柄,为什么不直接使用 shared_ptr 呢?

例如:

shared_ptr<void> file( CreateFile(L"la.txt", GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL), CloseHandle);   

DWORD written;
WriteFile(file.get(), //get handle
          "ABC\r\n", 
          5,
          &written, 
          NULL);

它在您的代码中占用的空间不大,您不必编写 40 个类。


您可以通过为每种类型 的关闭定义一些函数来避免每次都传递相关的关闭函数,例如:

auto make_handle_CloseHandle = [](HANDLE h){ return  (shared_ptr<void>(h,CloseHandle)); };

auto file = make_handle_CloseHandle(CreateFile(L"la.txt", /*same ...*/));

DWORD written;
WriteFile(   file.get(), //get handle
            "ABC\r\n", 
            5,
            &written, 
            NULL);

并将它放在相关命名空间下的某个头文件中,这样您就不必每次都键入关闭函数的名称,这些函数的用户将知道调用了哪个函数(根据 make_handle_* name) 这可能比尝试仅通过句柄自动识别句柄类型更安全。

关于c++ - 如何在运行时检查 Win32 句柄的 "type",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24890305/

相关文章:

c++ - vector.back() 的意外值

c++ - 独立于平台的图形用户界面

C++设置光标大小超过32

c++ - 将 lambda 传递给函数模板

c++ - 如何初始化用 auto 关键字声明的循环计数器?

c++ - 不应该禁止访问私有(private)类型吗?

c++ - 试图理解 C++14 中的 [expr.const]

c++ - 根据 "auto(x)"论文(wg21.link/p0849),为什么 "return std::forward<T>"无法完美转发 "T&&"输入的参数?

c - 使用第二个参数的 ReadConsoleOutputCharacter 错误

windows - 更换开始菜单