8 ms·
COM+ Revisited
- jmull 5y agoSeems crazy to me to use WIL instead of ATL as your C++ COM wrapper.
- jstarks 5y agoCare to elaborate?
- andyjohnson0 5y agoWIL seems to be in more or less active development, according to its GitHub page. ATL doesn't seem to have much done to it in the last decade or so. https://github.com/microsoft/wil https://github.com/microsoft/wil
- jmull 5y agoCOM isn't changing. The entire point (the only point, actually) is interop. 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
- pjmlp 5y agoYou forgot C++/CX, WRL and C++/WinRT on your list. 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.
- nikanj 5y agoWRL is by far the best of the bunch. Instead of WE_ARE_THE_ATL(MACRO_POINTER$(##PLEASEREGISTER ^& CLASS)) you have class ListenerCallback : public RuntimeClass<RuntimeClassFlags<ClassicCom>, IWhateverListenerInterface [...] CoCreatableClass(ListenerCallback);
- pjmlp 5y agoI would be so happy if they ditched IDL, or at very least improved its development experience, specially with the excuse to wait for C++ reflection to give back the experience of using C++/CX with C++/WinRT, means I will probably retire before they even bother to start.
- bigbizisverywyz 5y agoMy preference is never to use _com_ptr_t et al. (instead CComPtr for a nicer RAII) since they throw exceptions, and almost none of the developers I worked with expected that, so lots of unhandled exceptions at runtime was the result. One of the best things about the COM (previously OLE) API was actually HRESULTS, so I always encouraged their use, and IErrorInfo wherever possible.
- mwattsun 5y agoI read about "Software ICs" in Byte Magazine in the 80's. I later thought COM was a decent try. The implementation and tooling around it was always problematic. People do buy software components off the shelf now, like special graphing controls in Excel for example, so it continues to be a useful paradigm. The Software IC concept got coopted by OOP, which isn't the way I first understood it. Graham Lee blog post about Brad Cox's Object-Oriented Programming: In 1714, Gottfried Leibniz published La Monadologie, in which he proposed that at the fundamental level, objects are made of indivisible entities called Monads. You can’t see inside a monad, it has an internal state that controls its actions and passions. Monads can be created or destroyed atomically, but cannot be partially built or partially annihilated because they are a “simple substance without parts”. Cox, on the other hand, opens with the story of Eli Whitney and the industrial revolution. For Cox, the industrial revolution is not primarily about machinery and the harnessing of steam and coal power. It’s about the replacement of artisanal, cottage manufacture with scaled-up industrial processes that depend on well-specified interfaces between standardized, interchangeable parts. https://web.archive.org/web/20191220204822/https://deprogrammaticaipsum.com/2019/12/02/brad-cox/ https://web.archive.org/web/20191220204822/https://deprogram... https://news.ycombinator.com/item?id=21833331 https://news.ycombinator.com/item?id=21833331
- panta 5y agoThanks for writing about these. That "Software ICs" article has been a strong source of inspiration. It's maybe worth noting that Brad Cox was the inventor of Objective-C (which was seen as a way to allow the creation of software ICs, and was inspired also by Smalltalk).
- bigbizisverywyz 5y agoAnd speaking of RPC and COM+ ... Here's what I believe inspired a lot of what's in DCOM and COM+ (formally MTS) https://developer.apple.com/documentation/foundation/nsdistantobject https://developer.apple.com/documentation/foundation/nsdista...
- mandarax8 5y agoDo people still code like this?
- mwattsun 5y agoYes Introduction to Fuchsia components Components are the foundational building blocks of software running in Fuchsia. Each component is a composable, sandboxed module that interacts with other components through capabilities. https://fuchsia.dev/fuchsia-src/concepts/components/v2/introduction https://fuchsia.dev/fuchsia-src/concepts/components/v2/intro... COM+ Application Overview https://docs.microsoft.com/en-us/windows/win32/cossdk/com--application-overview https://docs.microsoft.com/en-us/windows/win32/cossdk/com--a...
- pjmlp 5y agoYes, Windows is mostly COM nowadays, when it isn't .NET. Then you have XPC on Apple platforms, Android IPC and Fuschia IDL on Google's, D-BUS on GNU/Linux, and the new cloud fashion gRPC.
- wila 5y agoWhat is fun is that so many people say "but COM is outdated"... when I look around in Windows it is everywhere. :)
- pjmlp 5y agoMostly because they didn't got the memo and think .NET replaced COM. Which was kind of the original idea, but then with Longhorn WinDev wasn't happy with how things were going, so instead of doing like Google with Android, pushing the new stack no matter what, they worked against it. So when the reboot that would become Vista started, all Longhorn ideas got redone as COM instead of .NET. And since then all major APIs are COM based, eventually with .NET bindings as well.
- tonyedgecombe 5y agoYes, Manu's comic is spot on on this: https://en.wikipedia.org/wiki/Manu_Cornet#/media/File:%22Org_charts%22_comic_by_Manu_Cornet.png https://en.wikipedia.org/wiki/Manu_Cornet#/media/File:%22Org...
- RantyDave 5y agoCOM is (IMHO) one of the great underrated technologies. Registering all the classes, interfaces etc. in the registry - not so much. But IDL's, versioned interfaces etc. etc. are all reinvented every five years or so. And it's fast as hell. DCOM was awful.
- jeffparsons 5y ago> But IDL's, versioned interfaces etc. etc. are all reinvented every five years or so. And it's happening again right now, albeit for a better reason than normal. The WebAssembly Component Model (currently in development) draws heavily on lessons from all these generations of reinvention, and especially from COM itself.
- YZF 5y agoWasn't that awful ;) In some sense it's maybe a precursor to gRPC. DCOM let us (EDIT: us being some old project/team I worked on) take a component and make it distributed with very little work (COM -> DCOM) almost seamlessly.
- RantyDave 5y agoInteresting, I was obviously doing something very wrong (back in the day).
- city41 5y agoIt's been many years for me, but I remember it having nice interop with .NET as well. Back then I worked with several APIs that were just COM objects brought into .NET.
- smackeyacky 5y agoI worked on a project around the early 2000s that had a mixture of DCOM and Corba in it. Relatively speaking, DCOM was a dream. It reminded me a lot of the original RPC generated stubs on Solaris. Corba reminded me that some people should never write network code: sometimes the interface would start, sometimes it wouldn't (this system was a consumer of something the Corba system was generating). The Corba guys had an elaborate startup procedure that resembled praying to the gods of Java that it would work this time, Bullwinkle pulling a rabbit out of a hat style. The DCOM stuff just worked / was able to reconnect when something failed. Corba was possibly the worst tech I have ever had the displeasure of using and while I don't remember DCOM especially fondly, it wasn't terrible.
- Const-me 5y agoI like many parts of COM, but I believe that example mostly demonstrates bad parts, with IDL, registrations, and over-engineered support libraries. There's nothing wrong with exporting factory functions from DLLs. Microsoft does it all the time, APIs like Direct3D, DirectDraw and Media Foundation don't come with type libraries are they aren't registered anywhere. Speaking about support libraries, I once made my own: https://github.com/Const-me/ComLightInterop/tree/master/ComLightLib https://github.com/Const-me/ComLightInterop/tree/master/ComL... Compare examples from that article with this one: https://github.com/Const-me/ComLightInterop/blob/master/Demos/HelloWorldCpp/HelloWorld.cpp https://github.com/Const-me/ComLightInterop/blob/master/Demo... That source file is the complete DLL which implements a minimalistic COM object.
- pjmlp 5y agoWith C++/CX and .NET Native they finally got it, after all these years Microsoft actually adopted Borland's productivity to COM, as done by C++ Builder and Delphi. Then they just managed to sink that ship with their UWP execution and the anti-C++/CX team that managed to deprecate it in name of C++/WinRT. It wouldn't be that bad if IDL tooling had actually improved since the ActiveX days.
- _0w8t 5y agoMedia Foundation is registered as one is supposed to use CoCreateInstance() etc. to create various codecs, for example. But MF does not require CoInitialize() and indeed one can just use LoadLibrary() and lookup the factory function. That was handy when we needed to use MF in a sandboxed process when CoCreateInstance would fail due to sandbox restrictions on registry access.
- Const-me 5y ago> Media Foundation is registered Good point, albeit I think only higher-level pluggable pieces are registered. Most of these objects (IMFTopology, IMFSample, IMFMediaBuffer) can only be created with corresponding C APIs. > one is supposed to use CoCreateInstance() etc. to create various codecs I’m not sure about that, I think one is supposed to use APIs like MFTEnumEx to find and create these codecs. These things are also in registry, but in different key; CoCreateInstance normally looks under HKCR\CLSID but MF has another one, HKCR\MediaFoundation\Transforms. See also MFTRegister function, a quote from the documentation: This function does not register the CLSID of the MFT for the CoCreateInstance or CoGetClassObject functions
- 0x0 5y agoI always wondered if COM+, the new version of COM, was originally going to be named COM2 ... until somebody tried to create a new visual studio project in a directory named COM2...
- mgsouth 5y agoIn case you're going "???"--MS-DOS and (until xx?) Windows treated some file names as special device names: CON, PRN, AUX, NUL, LPTn, COMn,...[0] And even if Windows supports (or hides) it now, no doubt ramifications linger on in apps. [0] https://en.wikipedia.org/wiki/Device_file#PC_DOS,_TOS,_OS/2,_and_Windows https://en.wikipedia.org/wiki/Device_file#PC_DOS,_TOS,_OS/2,...
- davidpolberger 5y agoI spent a couple of years (while working a full-time job) writing my master's thesis on "component technology" -- COM, CORBA, .NET assemblies, OSGi and the COM-inspired object model developed at Ericsson and Sony Ericsson for use in cell phones. This was back in 2009. I tried to make sense of how all these disparate technologies fit together. Give it a read if you like (CC-licensed): http://www.polberger.se/components/ http://www.polberger.se/components/ http://www.polberger.se/components/read/ http://www.polberger.se/components/read/ http://www.polberger.se/components/thesis.pdf http://www.polberger.se/components/thesis.pdf
- gavinray 5y agoThis is really interesting, thank you for sharing. I downloaded the PDF of your thesis and put it in my to-read library.
- davidpolberger 5y agoNice, let me know if you have any questions or feedback! (Email in profile.)
- skyde 5y agoyou are the expert so please correct me if I oversimplify> to me .net assemblies and Java JAR files are just a portable DLL (because they use bytecode and support reflexion). OSGi seem to push the concept further and try to define how plugin should integrate in a hosting application (ex: eclipse ID plugin, web browser extension ...) The way OSGi try to achieve this is by defining protocol for dependency injection (Services Registry, Modules, Life-Cycle inteface ..) I never really understood COM, I built some OCX module for visual basic 6. I have been told OCX are ActiveX control and that ActiveX control are based on COM but this is all confusing.
- davidpolberger 5y agoIt all depends on how you define a software component. I use one definition in my thesis, and I argue that .NET assemblies satisfy that definition, as do OSGi bundles (but not plain JAR files). (There have been many, many attempts at defining a software component, and they tend to be incompatible with one another.) In the end, it doesn't much matter. I chose a topic for my thesis way back in 2005, and at that time, there was some academic interest in what was called Component-Based Software Engineering (CBSE). That interest, as far as I can tell, evaporated pretty quickly.
- jbandela1 5y agoA few years back, I wanted to see what you could do if you really used modern C++ with the COM principles. This is what I came up with: https://github.com/jbandela/cppcomponents https://github.com/jbandela/cppcomponents * There is no code generation or IDL files * Components implement IUnknown * You can have Constructors and static functions for C++ classes. * You can take std::vector, std::string, std::tuple as parameters and return them (even if you are using different compilers and standard libraries) * Cross-platform
- userbinator 5y agoCOM has always felt like one of those "OOP and architecture astronautism gone off the deep end" technologies. A ton of boilerplate and indirection to do very little, with the associated bloat at both development and runtime. All the times I've used it, it was not because I wanted to, but because I was forced to. Here's a fun contrast/example: https://docs.microsoft.com/en-us/windows/win32/dlgbox/using-common-dialog-boxes#opening-a-file https://docs.microsoft.com/en-us/windows/win32/dlgbox/using-... https://docs.microsoft.com/en-us/windows/win32/shell/common-file-dialog#basic-usage https://docs.microsoft.com/en-us/windows/win32/shell/common-... Non-COM: fill in a structure and call a function. COM: make a dozen (doubly-)indirect function calls.
- marstall 5y agolol #1 ... looks straightforward ... #2 brain shuts off instantly
- colejohnson66 5y ago#2 is horrid, but could be solved by inverted if conditions and a single “cleanup:” label with goto: if (!SUCCEEDED(hr)) goto cleanup;
- benibela 5y agoOr: if (SUCCEEDED(pfd->Advise(pfde, &dwCookie)) && SUCCEEDED(pfd->GetOptions(&dwFlags)) && SUCCEEDED(pfd->SetOptions(dwFlags | FOS_FORCEFILESYSTEM)) && SUCCEEDED(pfd->SetFileTypes(ARRAYSIZE(c_rgSaveTypes), c_rgSaveTypes)) && ... )
- userbinator 5y agoThe point is that all those function calls aren't necessary, nor could the majority of them ever fail. Assigning to a field in a structure doesn't fail nor result in a function call.
- nikanj 5y agoNon-COM: The function needs to be in your process. Unless you're committing deep heresy, it'll have to be written in the same language as the code you're writing right now COM: The function can be in the same process. It can be in another process. That process might be written in a different language, or running on a different computer. The best we've come up with to actually mimic the COM feature set is doing HTTP. For some reason, a large subset of programmers seem to think "complex=slow", and truly believe that JSON is faster than binary-packed structures. The performance of COM is incredible. In-process servers are practically just as fast as calling native functions. Out-of-process servers are still plenty fast, because you don't have to go opening TCP sockets, doing HTTP request parsing, etc.
- pronlover723 5y agoI remember using the OLE COM viewer and seeing all the 1000s of APIs I could call. Some of them even had embedded docs. I always thought "wow! if I only I had an idea I could use all these apps and libraries together".... but I never did https://flylib.com/books/en/3.294.1.109/1/ https://flylib.com/books/en/3.294.1.109/1/
- tezheng 5y agoI noticed IGameObject in the post. I've been playing with both Unity3D and COM for several years, and kept thinking about the similarities. COM has been considered bad constantly, but base on the popularity of Unity3D, IMHO COM theory shows its advantages in building an open system(plugin-friendly).
- MichaelMoser123 5y agoWow, haven't heard about COM/DCOM for over twenty years (though i had some flashbacks, when starting with gRPC). I remember they had an evangelist named Don Box, i think he even had a tattoo on his body that had to do with COM; Now wikipedia says that he worked at microsoft until last year, i wonder what he is doing now. https://en.wikipedia.org/wiki/Don_Box https://en.wikipedia.org/wiki/Don_Box I mean, if one would tattoo some software architecture, then one would have to change the tattoo every ten years, as the subject inevitably becomes obsolete; bother! well, almost everything becomes obsolete, with the exception of Unix; that fact could serve as an indication for the alien origin of this operating system ;-) Another flashback from working with Windows: the MSDN CDs had the best documentation that i ever saw; no one comes even close...
- pjmlp 5y agoExcept COM isn't obsolete and since Vista is the main delivery mechanism for native APIs on Windows, UWP is basically COM with TLB replaced by .NET metadata and some ABI improvements.
- MichaelMoser123 5y agoBut .NET isn't relying on COM as an RPC mechanism, isn't it? They had something else, last time that i checked. I think that one would be better off with gRPC, if one isn't a windows only shop, and if one is working with some kind of mixed deployment.
- pjmlp 5y agoYou mean remoteing, then WCF, now replaced by gRPC. However the RPC stuff you are thinking about is DCOM. COM by itself is an OOP ABI, for dynamic libraries that can either be consumed in-proc, or out of process for safety reasons and easier cross language interoperability.
- MichaelMoser123 5y agoI think that DCOM can be used for communication between threads, when used in-proc with the appartment model, if memory serves me well. However in this case they are sending windows messages between the communicating threads, i think that this mechanism isn't very lightweight, as opposed to how it was advertised back then.
- hbarka 5y agoI can recall how easy it was to write and compile a COM dll and have it running instantly in IIS. Everyone running Windows Server 2nnx had IIS. It was a time to be alive.