Simple objects are just a
struct containing all the fields. Methods typically take a pointer to that
struct as their first argument (like python does). This simple form of OOP is done all the time in C.
Inheritance makes things more complicated. You can add a pointer to the parent object from the child object, or include all the parent's fields. Virtual methods require a vtable as part of the struct, which is basically function pointers for every virtual method. You need to add code that handles polymorphic dispatch. Look at GObject for a good production-quality example of this kind of OOP in C.