pjmlp 7 years ago

COM is pretty much alive on the Windows world.

After winning the war against the Longhorn team, the Windows team picked up their .NET ideas and reimplemented them in COM.

So since Windows Vista the large majority of new Windows APIs got implemented as COM.

With the Windows 8 release, an improved COM was released as WinRT, which basically picked up on the ideas of COM Runtime before it got redone as CLR.

After that we got UAP with 8.1 release, as the phone, tablet and desktop APIs got a bit closer.

Then with Windows 10, we UWP as the whole set of APIs (IoT, phone, tablet, desktop and XBox) got the same common base.

Every single Windows 10 release has been closing the distance between legacy Win32 and modern UWP, bringing the models together and merging the sandbox models (old style Win32 and UWP).

At BUILD 2019, Microsoft also announced that they will be rewriting React Native for Windows on top of UWP.

Meanwhile C++/CX was deprecated, and thanks to the work lead by Kenny Kerr, it got replaced by C++/WinRT, a C++17 compliant framework for doing UWP programming on Windows (aka Modern COM).

BUILD 2019: "Meet C++/WinRT 2.0: Faster and smarter in the open"

https://www.youtube.com/watch?v=X41j_gzSwOY

davidpolberger 7 years ago

If you're looking for a gentle and free introduction to COM and a few other component and object models, you could do worse than my thesis from 2009 (licensed under a Creative Commons license):

http://www.polberger.se/components/read/

When Ericsson's cell phone business split into Ericsson Mobile Platforms (EMP) and Sony Ericsson (SEMC) back in 2001, they created an object model named Ericsson Component Model (ECM/OPA), which was heavily inspired by COM. The intent was to create an API separating the lower-level Ericsson software from the user-facing software developed by Sony Ericsson.

Sony Ericsson then expanded upon ECM, calling it ECM Extended (or ECMX, though the technology was universally known as "IDL" internally). ECMX was supposed to enable their aging software stack to be modularized by providing an object model for code written in C.

For the future, though, they wanted to switch to writing application code in Java. Back in these feature phone days, Java games were written to Sun Microsystems's MIDlet specification. Sony Ericsson expanded upon that specification and created the SEMClet specification for their internally-developed applications. By writing software in Java and not C, Sony Ericsson not only wanted to use a modern, garbage-collected language, they also wanted to break free of their monolith. All native code was linked together statically as this monolith, and this process could take hours. MIDlets and by extension SEMClets could be installed dynamically, significantly streamlining development.

ECMX was the technology used to enable SEMClets to communicate with native code. If you're familiar with Mozilla and XPCOM, this may all sound very familiar -- and you'd be right.

All this was back in 2005, when I did my thesis work as part of Sony Ericsson's software architecture group. As part of that work, I had to figure out what COM was, what it really meant for COM to be a binary standard (and how that differed from the approach taken by CORBA) and how all that fit together with the Java component model OSGi, .NET assemblies and ECM/ECMX. I felt that I had to have a handle on all that history in order to write my thesis.

None of this is very fashionable today, but I still think that there's a lot we can learn from this era.

chaoticmass 7 years ago

Reading about COM really takes me back to my VisualBasic (classic) days. I was an inexperienced teenager at the time, and I remember the excitement I'd get when browsing through the different COM controls I could add to my projects, picking some just to see what they did and trying to figure out how to use them (pre-Google and mostly didn't have internet at home at the time). Learning to make my own COM controls and distribute them was highly instructional, if also maddening at times when trying to get the right version of a .DLL registered and installed.

  • gregschlom 7 years ago

    Was going to write exactly the same thing!

  • aitchnyu 7 years ago

    I was 11, but I managed to make a HTML page which played Shrek trailer from filesystem on loop (with audio of course) and mount that as wallpaper in Windows 98. Frontpage, IIRC.

kazinator 7 years ago

> Object enabling technology consisting of an simple yet elegant object model and a lightweight runtime support system sufficient for implementing language-independent objects on virtually any platform that supports dynamic linking.

I don't know about elegant, but circa 2001, I ported some COM objects to Linux, including enough of the surrounding Win32 API's to make it work. I had a fake registry based on text files, with CoCreateClass and all that junk working. The shared libs continued to have a DllMain, and DllCanUnloadnow and so on.

pjmlp 7 years ago

One thing from SOM that made me envy was that SOM had metaclasses, just like Smalltalk, so it was possible to do some interesting designs.

COM Type libraries and now UWP metadata aren't really the same.

DonHopkins 7 years ago

This article comparing SOM and COM was written by Don Box. (first archived in January 1999, but doesn't say when published):

The Component Object Model and Some Other Model: A comparison of technologies revisited yet again:

https://web.archive.org/web/19990127184653/http://www.develo...

https://en.wikipedia.org/wiki/Component_Object_Model

It was in response to IBM's somewhat misleading article comparing their SOM with Microsoft COM, last updated July 1994:

The System Object Model (SOM) and the Component Object Model (COM): A comparison of technologies summarized

https://web.archive.org/web/19990117055950/http://www.develo...

https://en.wikipedia.org/wiki/IBM_System_Object_Model

Don Box wrote an excellent in-depth book about COM: "Essential COM": "Nobody explains COM better than Don Box" -Charlie Kindel, COM Guy, Microsoft Corporation.

https://en.wikipedia.org/wiki/Don_Box

https://archive.org/details/essentialcom00boxd

Unfortunately COM had the most un-googlable name possible (even before there was a Google), so Microsoft renamed it ActiveX.

For more comtext, here are some notes I wrote about Win32, COM, OLE, OLE Controls, and ActiveX in 1996:

https://donhopkins.com/home/interval/pluggers/win32.html

https://donhopkins.com/home/interval/pluggers/com.html

https://donhopkins.com/home/interval/pluggers/ole.html

https://donhopkins.com/home/interval/pluggers/olecontrols.ht...

https://donhopkins.com/home/interval/pluggers/activex.html

Here's a synopsis of COM I wrote in response to "Can someone link to a synopsis describing what "COM" is? It's hard to search for. (e.g. microsoft com visual studio)":

https://news.ycombinator.com/item?id=12975257

Don't get me wrong: I'm not advocating everybody jump on the COM bandwagon! I just think it's interesting and useful to know where it came from, how it evolved, what different layers were built on top of it, and how it compared to the alternatives at the time it was designed. And it's still pretty widely used, and will probably never go away.

It certainly had a lot of problems and limitations, and OLE/ActiveX/DCOM/DirectX/etc took it way too far, then Mozilla XP/COM cloned it and also took it way too far (and then back again: see "decomification" and "decomtamination"), but it really was a pretty elegant and successful solution to the problems it was designed to address at the time.

https://wiki.mozilla.org/Gecko:DeCOMtamination

https://news.ycombinator.com/item?id=12968830

https://bugzilla.mozilla.org/buglist.cgi?query_format=specif...

It's always good to study history to avoid repeating the mistakes of the past!

WebAssembly is going through a similar evolution, and might benefit from some of the lessons of COM and SOM.

  • optimiz3 7 years ago

    > Unfortunately COM had the most un-googlable name possible (even before there was a Google), so Microsoft renamed it ActiveX.

    All ActiveX components are COM components, but the opposite is not true.

  • tonyedgecombe 7 years ago

    Don Box wrote an excellent in-depth book about COM: "Essential COM"

    It's on my desk right now, I was relatively inexperienced when I first read it so I thought it might be worth another look 15 years later.

pvg 7 years ago

There's also a (deliberately provocative) bit Rob Pike wrote - "There has been much talk about component architectures but only one true success: Unix pipes"

  • DonHopkins 7 years ago

    ITS had "Core Link Interrupts" for sending messages between processes and implementing cool features like "EVAL-IN-OTHER-LISP":

    https://web.archive.org/web/20110720170137/http://www.sigfs....

    3.4.3 The CLA, CLI, CLO and CLU Devices

    These symbolic devices enable arbitrary pairs of procedures to talk to each other as buffered input-output devices. Each file on any of these "core link" devices represents a 200 word area, most of which is buffer, which may be simultaneously open for reading, writing, both or neither. The files are identified by two regular file names and a system name [Sec 2.2, 2.2.3]. Only one procedure at a time may have a core link open to write or read on one channel. All standard modes are available.

    The CLO (Core Link Open) device may be used to open any core link file and (whether reading or writing) will create one if none exists with the name used. The CLU (Core Link Use) device is identical except that an .OPEN on it will fail if the referenced file does not already exist.

    Core link "files" have some peculiar properties. When writing a core link, a procedure will hang if the buffer is full and will write an end-of-file mark outside of the data stream when it closes the channel it has the file open on. However, opening and writing again the same file name essentially pushes a new block of data into the pipeline to be removed by a reading procedure. A procedure reading a core link can not read past an end-of-file and must close and reopen the file if it suspects that there is more to follow. If a reading procedure closes a core link before encountering an end-of-file, remaining information until the end-of-file is ignored. Core link "files" cease to exist only if empty and open for neither reading nor writing or not empty and not open for from two to four minutes. In the later case they are expunged by the system job [Sec 6.5] to unclutter the system.

    The CLI (Core Link Interrupt) device may only be opened to write. The two file names specified should be the UNAME and JNAME [Sec 5.1] of a procedure in the system with the CLI interrupt [Sec 4.2] enabled. If ther is no existing core link with the file names and system name used, the .OPEN will succeed in creating a link and interrupting the specified procedure. In addition ITS inserts in the created link two words of information as the start of the first file. These are the UNAME and JNAME of the .OPEN'ing procedure.

    The CLA (Core Link Answer) device is to be used in response to a CLI interrupt. It may only be opened for reading and scans through all existing links for one with file names the same as the UNAME and JNAME [Sec 5.1] of the procedure doing the CLA open. If one is found not already open for reading, the .OPEN succeeds.

    https://www.reddit.com/r/programming/comments/t4rre/common_l...

    http://www.maclisp.info/pitmanual/system.html

    The following is some sample code (complete with documentation) that I found in my notes and thought might be helpful:

        ;;; Notes about CLI interrupts:
        ;;;
        ;;; A CLI interrupt is what happens when another job sends to yours. It is
        ;;; normally the case that other jobs will send directly to a user's HACTRN.
        ;;; If, however, Lisp is interrupted by a CLI message, it can elect to handle
        ;;; handle the interrupt in an arbitrary way.
        ;;;
        ;;; To define a handler, two things must be done:
        ;;;  [1] Place the name of the handler function (function of one arg)
        ;;;  in the variable CLI-MESSAGE.
        ;;;  [2] Enable CLI handling with (SSTATUS CLI T)
        ;;;
        ;;; The handler should take a single argument which it probably should ignore
        ;;; since I have no idea what it is likely to be.
        ;;;
        ;;; The handler should open the file "CLA:" in (CLA BLOCK) mode and immediately
        ;;; discard the first 8 characters which will be garbage.
        ;;;
        ;;; The remainder of the stream, until a control-C or an eof, will be the text
        ;;; of the message sent. It may be read with TYI, READ, etc. and handled 
        ;;; however.
    
        (eval-when (eval compile)
          (cond ((not (get 'iota 'version))
                 (load "liblsp;iota"))))
    
        (defun handle-cli-msg (ignore)
          (iota ((stream '((cla)) '(cla block)))
            (do ((i 0 (1+ i))) ((= i 8)) (tyi stream))
            (do ((c (tyi stream -1) (tyi stream -1)))
                ((or (= c -1) (= c 3)))
              (format t "~&~3,'0O ~@:C~%" c c)))) ;print out chars seen
    
        (setq cli-message 'handle-cli-msg)
    
        (sstatus cli t)
    
        ; --------
    
        (defun eval-cli-msg (ignore) ;alternate handler
          (iota ((stream '((cla)) '(block cla)))
            (do ((i 0 (1+ i))) ((= i 8)) (tyi stream))
            (do ((f (read stream nil) (read stream nil)))
                ((null f))
              (errset (eval f) nil)))) ;Quietly evaluate forms...
    
        ;; Assumes the other lisp will have EVAL-CLI-MSG as value of CLI-MESSAGE
    
        (defun eval-in-other-lisp (uname jname s-expression)
          (iota ((stream `((cli) ,uname ,jname) '(out ascii block)))
            (print s-expression stream)))
        SYS-DEATH Value NIL
    • pvg 7 years ago

      Hah. One could probably make a decent (with [in]conclusiveness to taste) Worse is Better case study out of this.

  • pjmlp 7 years ago

    COM has been a success on Windows.

    Plenty of companies live from selling ready made components to integrate into Windows applications.

    How many are making a business from selling UNIX pipes?

    • pcwalton 7 years ago

      This is a silly framing, but I'll bite: All Chromium and Gecko browsers are based on Unix pipes (and Windows named pipes) for IPC. Chrome and Firefox together bring in billions of dollars of advertising revenue.

      • DonHopkins 7 years ago

        Ironically, Firefox is also based on XP/COM (though less and less over time, thanks to deCOMification and deCOMtamination).

        • pcwalton 7 years ago

          Right. Note that at the time Gecko was initially developed, it wasn't at all clear that JS would win. Having to support VBScript in addition to JS was a very real possibility. So COM made a certain amount of sense as a way to expose Web APIs to multiple languages simultaneously.

          Thankfully, the Web avoided VBScript, and later Dart.

          • pjmlp 7 years ago

            Given market share of Chrome, WebAssembly and Flutter, you should hold on to that "thankfully".

            Also from BUILD React Native talks regarding React Native vs Electron performance on Windows, I wouldn't be surprised if VSCode eventually moves away from Electron into React Native.

            • pcwalton 7 years ago

              > Given market share of Chrome, WebAssembly and Flutter, you should hold on to that "thankfully".

              WebAssembly doesn't need COM because it's integrated into the JS engine and uses the same JS engine bindings.

              I don't think anyone, even Googlers, seriously thinks that native Dart is going to make it onto the Web at this point.

              • pjmlp 7 years ago

                Chrome never used COM as part of its implementation.

                My reply had nothing to do with it.

                Naturally from Mozilla's employee point of view it is easier to ignore what I actually meant.

      • pjmlp 7 years ago

        Doesn't look like selling software components to me.

DonHopkins 7 years ago

"First there were VBXs. Then there were OCXs. Then, Microsoft wanted us to call them OLE Custom Controls, but we persisted in calling them OCXs. So they must have figured that we wouldn't accept any control technology that didn't have a name ending in X." -Curt Hagenlocher