Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 375
links77 Avatar asked Apr 20 '11 19:04

links77


1 Answers

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.

like image 123
Johann Gerell Avatar answered Nov 01 '22 23:11

Johann Gerell