See the question and my original answer on StackOverflow

You do lightweight COM when you use VTable binding (also used to be called "early binding") + the IUnknown definition. That's about it. You'll never find a definition of that in ancient Microsoft publication, because it never existed with this name.

As an API developer, when you declare you do "lightweight COM", you basically declare that you don't care about the following:

  • Object definition (ODL/IDL, metadata, TLB, type system, etc.)
  • Object activation (registry, progids, CoCreateInstance, etc.)
  • Object RPC (Cross thread or process marshaling, proxy/stub, etc.)
  • Automation (VARIANT, BSTR, universal marshaler, late binding, support for scripting languages, etc.)
  • Component services (Object Pooling, Surrogates, DLLHost, MTC/DTC, etc.)

Note that does not mean you won't have it, in fact, you will have it for free depending on the tooling you use (namely Visual Studio tooling, for example, it's somehow easier to rely on (M)IDL for the abstractions it provides), it's just that you like the idea of having an extensible API (with COM, you can "cast" objects between binary components) without the burden of supporting all these services.

Note also that "lightweight COM" is very very very portable across any platform and any language (call it "open") which is today more interesting.