So why is your language-specific wrapper changing? Well, for continued language support... but that does appear to be happening with ATL.
Call me skeptical, but we now have... let's see... four COM C++ API's to choose from, just considering the ones affiliated with MS. (If someone offered me an even bet there weren't more without looking it up, I'd take that bet).
Maybe, since the entire point is interop, we should settle on one at some point??
(1) raw C API IUnknown/BSTR/VARIANT/etc; (2) CComPtr/CComBSTR/CComVariant/etc; (3) _com_ptr_t/_bstr_t/_variant_t/etc; (4) WIL's baby COM API
Yep it is that bad.
The problem with ATL is that it is stuck in the Visual C++ 6.0 tooling experience.
The alternatives aren't much better though, although WIL seems to be the less painful to use, if we ignore all that UWP stuff.
WE_ARE_THE_ATL(MACRO_POINTER$(##PLEASEREGISTER ^& CLASS))
you have
class ListenerCallback : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWhateverListenerInterface
[...]
CoCreatableClass(ListenerCallback);
One of the best things about the COM (previously OLE) API was actually HRESULTS, so I always encouraged their use, and IErrorInfo wherever possible.