Obj.h
๐ OOP in pure C with a single-header
Install / Use
/learn @small-c/Obj.hREADME
obj.h
A single-header supports OOP in pure C.<br> Using power of preprocessor and hacking on assembly to unlock the limits.
<p> <a href="https://travis-ci.org/small-c/obj.h" target="_blank"> <img src="https://travis-ci.org/small-c/obj.h.svg?branch=master" alt=""> </a> </p>Foo f = new(Foo)(10); // create Foo instance
assert(f->get() == 10); // get value
f->base.release(); // release
Features
- [x] C++/Java inspired OOP
- [x] Public, private members
- [x] Constructor, destructor
- [x] Abstraction
- [x] Inheritance
- [x] Zero dependency
- [x] No breaking editor's intellisense
- [x]
x86/_64target - [ ]
armtarget
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:
static void fn_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
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.
<br>Related Skills
node-connect
347.2kDiagnose OpenClaw node connection and pairing failures for Android, iOS, and macOS companion apps
frontend-design
108.0kCreate distinctive, production-grade frontend interfaces with high design quality. Use this skill when the user asks to build web components, pages, or applications. Generates creative, polished code that avoids generic AI aesthetics.
openai-whisper-api
347.2kTranscribe audio via OpenAI Audio Transcriptions API (Whisper).
qqbot-media
347.2kQQBot ๅฏๅชไฝๆถๅ่ฝๅใไฝฟ็จ <qqmedia> ๆ ็ญพ๏ผ็ณป็ปๆ นๆฎๆไปถๆฉๅฑๅ่ชๅจ่ฏๅซ็ฑปๅ๏ผๅพ็/่ฏญ้ณ/่ง้ข/ๆไปถ๏ผใ
