用于句柄的 Win API 包装类

Posted

技术标签:

【中文标题】用于句柄的 Win API 包装类【英文标题】:Win API wrapper classes for handles 【发布时间】:2011-04-20 19:44:28 【问题描述】:

为仅按值传递的句柄编写包装类相对容易。我正在尝试确定封装需要按地址传递的句柄的最佳方法。

例如,为 SC_HANDLE 之类的东西编写一个通过值传递给 QueryServiceConfig() 的包装器并不难。可以实现一个成员函数,如 .GetHandle() 或实现 operator()

问题(至少对我而言)是像 RegOpenKeyEx() 这样的 API 函数需要 HKEY 的地址。

我读过重载运算符 & 通常是个坏主意。在允许 API 函数访问的同时保持封装(或尽可能多的封装),尤其是资源收集的推荐方法是什么?

【问题讨论】:

对于此类情况,我认为我更喜欢 Attach() 和 Detach() 模型。您可以实现一个 & 运算符,但我发现它非常丑陋。没有真正正确的答案。这更多是个人喜好。 【参考方案1】:

您始终可以添加另一层间接以避免operator& 和丑陋的AttachDetach 的严重过载,并从那里返回一个预包装的实例。

如果你可以在VS2010或gcc中使用C++0x,或者有其他方式访问std::unique_ptr<>,那么你可以这样做(为了简洁省略错误检查):

struct hkey_deleter

    void operator()(HKEY hkey)
    
        ::RegCloseKey(hkey);
    
;

typedef std::unique_ptr<HKEY__, hkey_deleter> regkey;

regkey MyRegOpenKeyEx(HKEY hKey, LPCTSTR lpSubKey, DWORD ulOptions, REGSAM samDesired)

    HKEY hOpenedKey = NULL;
    ::RegOpenKeyEx(hKey, lpSubKey, ulOptions, samDesired, &hOpenedKey);

    return regkey(hOpenedKey);


void SomewhereElse()

    ...
    regkey r = MyRegOpenKeyEx(HKEY_CLASSES_ROOT, nullptr, 0, KEY_READ);
    ...

hkey_deleter 将确保在退出范围或调用 regkey::reset() 时关闭注册表项。

【讨论】:

以上是关于用于句柄的 Win API 包装类的主要内容,如果未能解决你的问题,请参考以下文章

JAVA-初步认识-常用对象API(基本数据类型对象包装类-概述)

Win32 共享内存的包装类? (进程间通信)

J2SE核心开发实战——字符串与包装类

用于 kernel32.dll API 的包装器 C#

Java api 入门教程 之 JAVA的包装类

从零开始的Java开发1-5-2 包装类与基本数据类型常用API基本数据类型与包装类字符串之间的转换包装类的初始值与比较对象常量池