Hi all,
COM clean up is going well now (thanks Michael!) and after recent
conversation about wincodecs clean up, I had an idea about how to get
rid of even more casts. We could use widl to teach C a bit more about
interface inheritance, so that child->parent interface casts would work
in similar way as current obj->iface cast. I experimented a bit and
wrote a prove of concept patch for widl (see attached widl.diff). With
this patch, COM interfaces become unions in form like this:
#ifndef WIDL_TYPE_SAFE_C_INTERFACE
interface IWICBitmapFrameDecode {
CONST_VTBL IWICBitmapFrameDecodeVtbl* lpVtbl;
};
#else
union IWICBitmapFrameDecode {
CONST_VTBL IWICBitmapFrameDecodeVtbl* lpVtbl;
IWICBitmapSource base;
};
#endif
This is an opt-in macro based solution (so compatibility with standard C
interface is not a problem). You may see how this may be used in the
attached example of patch (wincodecs.diff).
Sadly, it has its drawbacks. Having interface as union instead of struct
breaks pretty sane assumption that interface==struct. Also there is no
portable way to statically initialize the interface for object-less
static interface implementation like:
IMyInterface iface_instance = { &MyInterfaceVtbl };
Since using this union based may be controlled per-file, it may not be
such a big deal, but I personally really like such constructs, esp. in
tests.
If we decide to use this solution, there are further decisions to to
(it's just a prove of concept now!):
- Naming convention. Is 'base' good? Should we use IIfaceName_iface
instead (seems too long)
- Sometimes &iface->base.base.base constructs will happen. Should we
have all parents, instead of only direct parent, in the union, so that
we can do iface->IUnknown_iface instead?
I don't have strong opinion myself yet, so I'd like to hear others'
opinions.
Cheers,
Jacek