I know, thus the /s for sarcasms.
> Such wrappers are fairly trivial to generate if you don't want to handwrite them.
It's fairly irrelevant to my point, which is that C structs aren't equivalent to Java classes in anyway.
Of course you can implement OO is C, I've done enough GObject in my life to know how horrible it is to use in practice.
Simple example here: https://embeddedgurus.com/state-space/2008/01/object-based-p...
Lots more here: https://stackoverflow.com/questions/351733/how-would-one-wri...
Embedding combined with the container_of-macro [0] is a much more constructive approach from my experience.
[0] https://stackoverflow.com/questions/15832301/understanding-c...
From a user point of view you end up doing things like:
string * str = string_new();
int len = string_length(str);
So it looks just like most other typical C code using prefixes per interface and passing pointers to structs around.In practice, like in C++, you'd tend to only actually use the vtable approach for those things which you actually need to be able to override based on type, which tends to be rare.
Another approach is to use messages instead, and a call a generic message handler. E.g. "ob->call(MSG_TYPE, ... arguments)" and just have a pointer to a message handler function as the first pointer in your objects. It's more flexible, but slower.
Oh.My.God.
At this point, you might as well be using Java.
But of course if you're going to reimplement OO from scratch in C you will see the entire machinery laid bare. You're only doing it in the first place either because you're committed to using C for whatever reason, or to understand OO implementation strategies.
If you want simpler models see my other comments in this thread.
You don't need macros. You either call via the vtable, or you write a wrapper per interface per message.
E.g.
Such wrappers are fairly trivial to generate if you don't want to handwrite them.If you want complex inheritance patterns, you might benefit from one more level of indirection, see e.g. Protocol Extension: A Technique for Structuring Large Extensible Software-Systems (M. Franz, 1995). That paper is for Oberon, but it's easily translatable to C - did that way back.
Upside is it let's you group functionality in interfaces with less of an explosion in vtable size, downside is the cost of one extra pointer indirection.