From: John Madsen (johnmadsen_usenet_at_[hidden])
Date: 2003-07-18 16:21:10


"Eugene Lazutkin" <eugene.lazutkin_at_[hidden]> wrote:
>I have a few comments in no particular order.
>
>1) I cannot imaging someone programming in C++ and using "FILE*s,and file
>descriptors" instead of iostream & Co. You've must be talking about
>incomplete systems like embedded systems, which don't have complete standard
>C++ library. Are there any real life examples for that? How frequent are
>they?
>

That's quite right. I don't see much use in having a wrapper for FILE*. File
descriptors' are a different story. Two cases that jump to mind are memory
mapped files and socket descriptors. In neither case are there general purpose
cross platform C++ libraries (that I'm aware of) that eliminate any reasonable
need to deal with file descriptors for these purposes.

The main uses of the library as I see it is to handle two main cases:

1) Where a programmer needs to access an API (whether it be from the OS or a
3rd party C API) which uses handle-based resource management and for which not
suitable C++ wrapper exists.
2) As an aid in implementing C++ wrapper classes for APIs mentioned in (1).

>2) Windows handles are problem indeed because they are not covered by
>standard libraries. MFC covers it but being a behemoth it is not suitable
>for some applications. ATL is better but it doesn't address handle issue. A
>lot of people and their grandma have created their own home-brewed handle
>wrappers.
>

Yes, one of purposes is to make this easier and to provide a semi-standard
interface.

>2a) You are not entirely correct in assumption that "Most Windows' handles
>are actually void pointers". For years Microsoft uses so called "strict
>definitions" by default (you have to switch to old mode explicitly). This is
>relevant code from their headers for illustration purposes:
>

[code snipped]

>As you can see HANDLE is void* but almost all other handles declared using
>DECLARE_HANDLE() macro, which makes them of different types. Notable
>exception is HGDIOBJ, which is void* as well. The former was done to
>facilitate inheritance-like relationship between generic GDI handle
>(HGDIOBJ) and specialized GDI handles (HPEN, HBRUSH, HFONT, HRGN, and so on)
>with C compiler.
>

I was unaware that this was now the default. However, the importance of the
RAII aspects of smart_handle still stand.

>2b) It appears to me that Windows handles and their profound importance are
>quite unique. I never struggled with something like that on X Window, for
>example. If this is the case, we are talking about platform-specific
>solution. I am not sure Boost is right place for platform-specific
>libraries. Of course, it is possible to make such library
>platform-independent but is it going to be used outside of Windows world?
>

I have little experience with X-Windows, so I can't comment on that. However,
there is absolutely *nothing* in the smart_handle library that is platform
specific. Just because one of the most obvious cases where it is useful is a
specific platform, does not make the library itself platform specific. I find
it hard to believe that there is no other C API which uses handles for resource
management that doesn't have a suitable C++ wrapper for every case other than
Windows.

>3) Necessity to call get() method every time you need to use handle is
>cumbersome. That's why auto_ptr or any other smart pointers define
>operator->() and operator*(). Instead of these operators smart_handle should
>define operator Handle() (where Handle is underlying handle type).
>

Six characters (".get()") doesn't seem cumbersome to me and seems much better
than a conversion operator which for many reasons is frowned upon. Note also
that auto_ptr and the like provide those operators so that they can actually
act like pointers. If you want the pointer value itself from an auto_ptr, you
call get(). Note also that std::string has c_str() rather than operator const
char*().

>4) Sometimes destruction of handles is more than a simple call to
>one-argument procedure. Real example from Windows, which is encountered
>frequently:
>
>HDC hDC = GetDC(hWindow);
>// do some drawing...
>ReleaseDC( hWindow, hDC );
>
>In this example destruction (releasing) involves some kind of context
>(window handle). Apparently it is not handled by proposed library.
>

Thanks for this example. I had not considered cases like this and will think
more about it.

>5) While I frequently needed scoped handles, I never encountered real need
>to have "weak" handles and reference-counted handles. When I wanted to do
>something like that, I created object, which was handled by smart pointer of
>some kind. Admittedly this is not light weight solution but it was never a
>bottleneck in my projects. Scoped handles are used extensively a should be
>as light weight as possible.
>

I agree that in many cases scoped is more useful. However, it was fairly
trivial to do shared and weak, so I figured why not? Also, shared_handles will
work in stl containers while scoped_handles will not.

>Thanks,
>
>Eugene
>
>PS: Yeah, I am one of those poor guys, who wrote Windows handle wrappers for
>themselves. If you want to take a look, I can send you a file.
>

I'd love to look at whatever you've got. You can send it to the no spam email
below if you'd like.

Thanks for your comments,

John

john at illura dot com