GitHub - small-c/obj.h: 🚀 OOP in pure C with a single-header (original) (raw)
obj.h
A single-header supports OOP in pure C.
Using power of preprocessor and hacking on assembly to unlock the limits.
Foo f = new(Foo)(10); // create Foo instance assert(f->get() == 10); // get value f->base.release(); // release
Features
- C++/Java inspired OOP
- Public, private members
- Constructor, destructor
- Abstraction
- Inheritance
- Zero dependency
- No breaking editor's intellisense
x86/_64targetarmtarget
Usage
- Just add
obj.hto your C source - See tests for more
C++ comparison:
// C++ native OOP // C with obj.h class Foo { | class(Foo, public( public: | int (*get)(); Foo(int bar); | ), private( int get(); | int bar; private: | )); int bar; | }; | ctor(Foo)(int bar) { | obj_setup(Foo); Foo::Foo(int bar) { | obj_bind(Foo, get); this->bar = bar; | self->bar = bar; } | obj_done(Foo); | } int Foo::get() { | return this->bar; | method(Foo, int, get)() { } | obj_prepare(Foo); | return self->bar; | } | Foo *f = new Foo(15); | Foo f = new(Foo)(15); f->get(); | f->get(); delete f; | f->base.release();
Platform support:
| GCC 4+ | MSVC 14+ | Clang 5+ | TCC 0.9 | |
|---|---|---|---|---|
| Windows (x86 / x64) | ✅ | ✅ | ✅ | ✅ |
| Linux (i386 / x86_x64) | ✅ | _ | ✅ | ✅ |
| Mac OSX (i386 / x86_64) | ✅ | _ | ✅ | _ |
- On Visual Studio 2017 15.8+, please disable Just My Code debugging
How it works?
We can't explain in detail, but something like binding
thisto a function in JavaScript.
Simulate a simple class with struct:
struct A { void (* todo)(); // method };
And we have a static function:
Next, bind A instance (aka this) to fn_todo 🙄
binded_todo = bind(fn_todo, myA);
Finally 😎
myA->todo = binded_todo; myA->todo(); // call it like a method
Closure function?
- This is a fork of yulon/clofn
- Just copy function header and inject some code to pre-allocate this inside
- Currently, support
x86andx86_64only
Function template:
static void fn_todo() { volatile size_t self = ...; ...
Disassemble:
; prolog mov rax, ... mov QWORD PTR [rbp-8], rax ...
Generated function:
[copied prolog]
x86 | mov eax, [data] | jmp [addr] x86_64 | mov rax, [data] | push rax | mov rax, [addr] | jmp rax
Refs:
How we provide classes, public/private?
See obj.h for more.