Boost logo

Boost :

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


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk