Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

History

204 Commits

Repository files navigation

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 instanceassert(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/_64 target
  • arm target

Usage

  • Just add obj.h to your C source
  • See tests for more

C++ comparison:

// C++ native OOP // C with obj.hclassFoo { | class(Foo, public(
public: | int (*get)();
Foo(int bar); | ), private(
intget(); | 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);
| }
intFoo::get() { |
returnthis->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)__

How it works?

We can't explain in detail, but something like binding this to a function in JavaScript.

Simulate a simple class with struct:

structA {
void (*todo)(); // method
};

And we have a static function:

staticvoidfn_todo() {}

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 x86 and x86_64 only

Function template:

staticvoidfn_todo() {
volatilesize_tself= ...;
...

Disassemble:

; prologmovrax, ...mov QWORD PTR [rbp-8],rax ...

Generated function:

[copied prolog]> x86| moveax,[data]| jmp[addr]> x86_64| movrax,[data]| pushrax| movrax,[addr]| jmprax

Refs:

How we provide classes, public/private?

See obj.h for more.


ko-fi

About

🚀 OOP in pure C with a single-header

Topics

Resources

Stars

134 stars

Watchers

5 watching

Forks

Contributors

Languages