Search code examples
c++windowswinapiraii

Win API wrapper classes for handles


Writing a wrapper class for a handle that only gets passed by value is relatively easy. I am trying to determine what the best way is to encapsulate handles that need to be passed by address.

For example, writing a wrapper for something like SC_HANDLE that gets passed by value to QueryServiceConfig() is not that difficult. One can either implement a member function like .GetHandle() or implement operator().

The problem (for me at least) is API functions like RegOpenKeyEx() that wants the address of a HKEY.

I've read that overloading operator & is generally a bad idea. What is the recommended way to keep encapsulation (or as much of it as possible) and especially resource collection while allowing API functions access?


Solution

  • You can always add another layer of indirection to avoid the awful overloading of operator& and ugly Attach or Detach and return a pre-wrapped instance from there.

    If you can use C++0x in VS2010 or gcc, or have other ways of accessing std::unique_ptr<>, then you can do this (error checking omitted for brevity):

    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);
        ...
    }
    

    The hkey_deleter will make sure that the registry key gets closed when the scope is exited or regkey::reset() is called.