Hacker News new | past | comments | ask | show | jobs | submit login
GObject (wikipedia.org)
58 points by tosh on Sept 2, 2017 | hide | past | favorite | 42 comments

GObject always felt like a poor man's Objective-C to me.

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 agree, Objective C was a nice little language. In the mid-90s I worked on one of the few (only?) non-NeXT Objective C projects, the Swarm Simulation System. We chose ObjC over C++ because it was simpler and more dynamic. At that time the GNUstep project was pretty new and most of the good stuff was in the GNU ObjC compiler and small runtime. It worked pretty well, particularly the very clever tclobjc binding that made it easy to script Objective C programs.

I've never used Apple's modern ObjC but from the code samples I've seen it got pretty complicated.

> few (only?) non-NeXT Objective C projects

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.

One might say complicated, I say feature rich! I think it's a shame that all focus is on Swift right now, because Objective-C has seen so many improvements in the last years, and it's now an incredible, mature language IMO. Wonderful to work in, and while I do dabble in Swift occasionally at work, and it has some neat features, I would still not choose it above Objective-C for any new stuff I'm building.

NeXT were hostile about open sourcing their Objective-C platform that was based on a fork of the GNU toolchain, indeed it was one of the early GPL enforement cases where lawyers got involved. But they still kept the runtime and li braries closed.

Obj-C is nice, but it's not like they couldn't use C++.

So why not just C++? why this obsession with C even when it makes no sense?

Traditionally C++ hasn't had a stable ABI. Object code from different compilers and even compiler versions has been incompatible. That made it a no-go for system frameworks.

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.

As an interesting tangent, to maintain BeOS compatibility, Haiku is still being built with a GCC 2.95 compiler. They also build with GCC 5 and a Clang port is underway, but those obviously loose compatibility.

How did Microsoft solve it with their C++ APIs? I've never ventured much into Windows programming, but I remember hearing that MFC uses C++, and newer stuff is mostly C++-based.

COM has some simularities to GObject, IMO.

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.

They carry around their bridge library called MSVC redistributable, and that one is tied to compiler version. Fortunately for them they don't release compiler versions too often, but stuff you have on your Windows install perhaps carries around half dozen of MSVC redistributable library sets.

All Windows APIs are still C (stdcall to be precise) with some COM.

> 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.

To clarify the above, new API's introduced since around Vista are more likely to be COM (and WinRT is of course entirely COM when used from C++), but the existing C API's have not been replaced, and some new C functions have been added since then as well.

During my life I didn't meet a single person who understood COM and could program with it.

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.

I don't think it's unreachable, and I know plenty of devs who understood COM. I think the issue was a mixture of failing to match expectations combined with very poor marketing (specifically, shoving too many things under the umbrella of COM).

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.

Ah the days of DCOM and MTS. :)

The core of COM is simple, elegant, and definitely "reachable". Don Box's "Essential COM" is a great book on the topic that clears away all the cobwebs that you fear are there. The more advanced topics do indeed become a bit more complicated.

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.

There is a subset of COM that is elegant and usable. And there is a ton of stuff that is only rarely used and understood. I'm looking at you, apartment models.

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.

> 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.

.NET was originally designed as COM+ Runtime, before they decided to create the CLR, the research project was called Ext-VOS.


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.

Usually everyone makes use of COM.

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.

EDIT: I think Ruby and Python can also consume COM. I also forgot to mention VBScript and JavaScript.

Because UNIX was always a C territory, it is like asking why the obsession with JavaScript on the browser.

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[0] 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.

[0]- https://www.gnu.org/prep/standards/standards.html#Source-Lan...

C is a vastly simpler language with good and well-tried semantics.

The simpler language spec may make sense to do OO with suboptimal tools vs C++.

> C is a vastly simpler language with good and well-tried semantics.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.

No one claimed gobject c was simpler to write than c++. That would be a foolish claim.

GObject has a much richer object model than what C++ provides out of the box. They could have used C++ and added the other semantics, but then you would end up with something similar to QObject in Qt and people would complain about that too.

> GObject has a much richer object model than what C++ provides out of the box. They could have used C++ and added the other semantics, but then you would end up with something similar to QObject in Qt and people would complain about that too.

But C compiler doesn't support GObject system. A C++ compiler obviously does support C++ types. GObject might be richer but writing GObject code is like coding in Javascript. The compiler isn't going to detect any of your type mistakes. this is not acceptable for someone who isn't familiar with GObject complexity. Qt is much much easier to work with, even for a bad C++ programmer.

Shudder. I remember looking st this 15 years ago, and it's a cruel joke. I understand why writing in C made multilingual bindings easy, but the ergonomics of GObject are horrible. You're stuck doing all the crap that real OO type system does, setting up vtables and what not. Most insulting, they dismiss(ed) all complaints as mere "syntactic sugar".

Ironically, I liked GTk+ back when I was doing that kind of stuff.

Nowadays there's Vala which is a C# like language compiled to C+GObject.

I agree. Using GTK+ for a small personal project made me realize just how unwieldy GObject is. Vala was a nice alternative, in my opinion, but it seems that everyone is trying to kill it off nowadays.

> but it seems that everyone is trying to kill it off nowadays.

What do you mean?

I also looked at gtk c++ programming in the late 90s and was disturbed by GTK--, the c++ binding at the time. The library used extensive template meta-programming that was so ugly that it made me give up on c++ as a language. The error mestages the compiler would vomit were often many lines long and took considerable time to decipher.

Gtkmm was what made GNOME programming a sane alternative to Qt, back in the day of the license wars.

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.

It's an entire portable object system. It does more than I suspect you think it does!

I think it does none of it in a way that's easy to use.

GObject is the most interesting source code in C I've read.

Could you explain? I'm probably not familiar with C to get why even if I tried it myself.

A little bit offtopic: I am somebody who has programmed in memory managed programming languages for all of my career. (With exception of Obj-C for a couple of years before ARC)

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.

There's also NSPR (Netscape Portable Runtime). Still maintained after all these years.


These are the two options I know of as well. Glib is relatively approachable imo, I also think the docs are better than apr, and there are more examples around. In the end I was interested in writing server apps, so I just used go.

glib seems to be a common go-to even for otherwise non-gnome projects

Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact