首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >如何在运行时检查Win32句柄的“类型”

如何在运行时检查Win32句柄的“类型”
EN

Stack Overflow用户
提问于 2014-07-22 22:36:21
回答 1查看 1.8K关注 0票数 1

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

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

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

EN

回答 1

Stack Overflow用户

发布于 2019-05-24 09:55:31

由于CreateFile的失败结果是INVALID_HANDLE_VALUE (-1),我不确定这是否是一个好的解决方案。

https://docs.microsoft.com/en-us/windows/desktop/api/fileapi/nf-fileapi-createfilea

实现某种shared_resource或unique_resource类型(接受模板参数或封装包装类型的特征的单个参数)可能是可行的,而不是使用旨在引用内存地址的内容。

我的代码看起来像这样:

代码语言:javascript
复制
template <typename TRAITS>
struct SharedHandle
{
....
}

它的用法如下:

代码语言:javascript
复制
struct TestTraits
{
    using HandleType = int;
    static constexpr HandleType INVALID = 0;
    static void Close(HandleType& h)
    {
        h = INVALID;
    }
};

using SharedHandleTestType = SharedHandle<TestTraits>;


TEST(ClvLib_SharedHandle_Tests, SharedHandle_default)
{
    auto tt = SharedHandleTestType();

    EXPECT_FALSE(tt);
}

TEST(ClvLib_SharedHandle_Tests, SharedHandle_good)
{
    auto tt = SharedHandleTestType(1);

    EXPECT_TRUE(tt);
}

TEST(ClvLib_SharedHandle_Tests, SharedHandle_use)
{
    auto tt = SharedHandleTestType(1);

    auto result = [](int t)->int {return t + 1; }(tt);
    auto expected = tt.Get() + 1;

    EXPECT_EQ(expected, result);
}

TEST(ClvLib_SharedHandle_Tests, SharedHandle_copy1)
{
    auto tt = SharedHandleTestType(1);
    auto t2 = tt;

    EXPECT_TRUE(tt);
    EXPECT_TRUE(t2);

    tt = 0;

    EXPECT_FALSE(tt);
    EXPECT_TRUE(t2);
}

TEST(ClvLib_SharedHandle_Tests, SharedHandle_copy2)
{
    auto tt = SharedHandleTestType(1);
    auto t2 = tt;

    EXPECT_TRUE(tt);
    EXPECT_TRUE(t2);

    tt = 0;

    EXPECT_FALSE(tt);
    EXPECT_TRUE(t2);

    t2.Release();

    EXPECT_FALSE(tt);
    EXPECT_FALSE(t2);
}

对于Windows文件句柄:

代码语言:javascript
复制
struct WinHandleTraits_IHV
{
    using HandleType = HANDLE;
    static constexpr HandleType INVALID = INVALID_HANDLE_VALUE;
    static void Close(HandleType& h)
    {
        CloseHandle(h);
    }
};

using WinFileHandle = SharedHandle<WinHandleTraits_IHV>;
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/24890305

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档