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