It's a shame that the language was so completely sidetracked in '90s open source Unix development. I suspect part of the blame goes to GNUstep's ambitious overreach. Maybe if they had just focused on an Obj-C widget toolkit instead of building an entire NeXT look-a-like desktop, it would have been more palatable to the wider community.
I've never used Apple's modern ObjC but from the code samples I've seen it got pretty complicated.
I worked on another, the Infopark Fiona content management system (formerly NPS). We started with the GNUStep foundation and later switched to libFoundation and a bunch of custom frameworks for Web and DB.
That experience made me realize that conventional wisdom was, as usual, wrong. It's not true that language is unimportant and only the frameworks count. With the right language, you can easily build the right frameworks for your needs.
There was/is also a bunch of telecoms work in messaging with GNUStep.
So why not just C++? why this obsession with C even when it makes no sense?
It's the same in Apple land: macOS uses a lot of C++ internally, but it's all wrapped into plain C APIs using an object system called CoreFoundation (which is IMO better than GObject because it was designed for "toll-free bridging" with Objective-C, so there is a low-friction path to a higher level language).
There have been operating systems that built their APIs in C++. BeOS and Symbian are the most notable ones. Both ran into serious trouble with the ABI being tied to a specific compiler, which in practice made it hard to port newer GCC or Clang.
What they did is they restricted themselves to the parts of the C++ ABI that are stable in practice. This is C exports, C types, and the layout of classes and vtables. COM is entirely usable from C (although cumbersome). The layout of a COM class/interface just happens to be the layout of a C++ class or vtable.
All Windows APIs are still C (stdcall to be precise) with some COM.
Only if we are speaking about until Vista.
With Vista the majority of Win32 API are only COM, not "with some COM", even the userspace drivers are COM.
WinRT introduced in Windows 8, nowadays rebranded as UWP, is also COM.
Of course one can be masochist and make use of the low level C compatible COM bindings, or embrace ATL, WTL, C++/CX or the new C++/WinRT and enjoy productivity.
That's it, just sayin'.
Maybe it IS awesome. It's just unreachable.
Borland made a fortune by making COM go away for a subset of tasks. After that, DotNet.
What people wanted COM to be was a way to share binary objects as DLLs—basically what the grandparent was assuming was actually the case on Windows. And at its simplest, COM is almost that. But what it actually did was provide something very different: a way to tell the OS, "Hey, I need you to give me an object that does X," where X was an interface you wanted the object to conform to, and then the OS would give you such an object, which you could address only by its interface. This is nothing more than factories/IoC in modern parlance, but it was new and confusing then, and people got frustrated.
Then, on top of that, Microsoft threw in a pile of other concepts. For example, if you want to use COM for system services, then, in the right situations, multiple people asking for a given interface could be given the exact same object—and this at a time when lots of devs weren't used to working with threading. And also, to accomplish that, you were doing local RPC, so here's also a full serialization framework, which you're probably also not used to. And also because now things are multithreaded a lot of the time, here's a way you can make your COM object single-threaded (think Java's synchronized keyword).
Nowadays, most of this isn't a big deal. Devs are used to RPC (via HTTP/JSON or things like gRPC and Thrift). They're used to factories and IoC. They're used to a single shared "object" being used by multiple processes in multiple services. But at the time, it was a lot of new stuff all at once, and I think it was just too much.
The core idea of COM is that you have objects that you solely interact with as a client by using interfaces. An interface is just a set of methods (under the hood, it's an array of function pointers, in the form of C++ vtables). An object can implement multiple interfaces.
So, for example, in the context of a videogame, you might have a player object that you can send joystick input to, you can render, and and you can persist to JSON. That object would have something like IInput, IRender, and IPersistence interfaces. If you have a reference to any of these interfaces, you can ask that interface for any of the other interfaces (QueryInterface).
At the heart of COM, that's really all there is to it. Method dispatch is as fast as C++ virtual functions because that's exactly what they are under the hood.
There are layers on top of COM which start to add complexity, particularly when you want interface/method discoverability. But you often don't need that, particularly when working with C/C++. I've worked with code (long ago) where just the core of COM was used, and it's really quite straightforward.
Basically, COM are conventions how to layout structs and name functions, such that other code can load your DLLs. Coincidentially, they are almost identical to C++ classes, so you can often just return a pointer to a C++ class.
There are layers and layers of conventions stacked, which makes it a bit complicated. On the low level, you can call stuff by knowing the memory layout. You have a header file and a pointer, and call the function at pointer+4. Fine for consuming from C/C++. Later, they developed IDispatch to call a method by string name (good for Visual Basic or scripting). There were interfaces to make Widgets (Custom controls / ActiveX). I personally found that the documentation for all that stuff was not very good.
However, it was fairly easy to create and consume COM components Visual Basic (and to some extend MSVC). There was a booming market for VB custom controls long before .NET. Its a bit unfortunate we don't have something like that today.
Sure we do.
And given that UWP and .NET Native are COM reborn, we will keep on having them.
Basically WinRT, being based on COM, with .NET being compiled to native code via .NET Native and UWP controls being implementations of IInspectable, is the return to that original design idea of the COM+ Runtime.
With Longhorn's failure, most of the .NET APIs that were part of the design how Longhorn was supposed to be, became COM APIs in Vista.
Since then all major APIs were always COM based, with WinRT design goal being to do with COM what was originally imagined for Longhorn.
Just that the COM APIs in UWP have been improved. Interfaces must inherit from IInspectable instead of IUnknown and .NET Metada is used instead of COM type libraries.
COM allows any language on Windows that can interface with it to have access to an OS OO ABI.
Which means any .NET language, Delphi, C++ and if feeling masochist C.
Back in the day, on the heat of the C vs C++ language wars on GNU/Linux, the C guys would pick GNOME and the C++ guys would be KDE.
Then there were those of us that would gladly pick KDE, if it wasn't for the license Trolltech was originally using, so there was the effort to create Gtk-- and Gnome--, which wasn't that well seen, back then.
Back then the GNU Coding Standards suggested using only C which helped language's adoption, in a world where OS/2, Windows, BeOS and Symbian were heavily adopting C++.
At least nowadays they acknowledge there are other programming languages that can be used.
The simpler language spec may make sense to do OO with suboptimal tools vs C++.
But GObject isn't a simple type system on top of C, A C compiler wont catch any GObject type error since everything is about casting "types" with macros, a C compiler has absolutely no understanding of GObject type system. I don't believe one second writing GObject code is simpler than writing C++ code, having looked at serveral GObject codebases.
Ironically, I liked GTk+ back when I was doing that kind of stuff.
What do you mean?
It was that template meta-programming that allowed us to offer the same event handling capabilities as Qt, without having language extensions based on an external tool like moc.
I recently wanted to try my hand at C. But was surprised that there isn't a Boost like lib for C.
What is a good generics/data structures library for C? Glib is one option. But it is supposed to be hard to use. Apache Portable Runtime seems to be another option. I read somewhere that its memory pools were considered to be a bad design and were supposed to be removed in the newer implementation. But the current stable version seems to use them.