Objectively
Ultra-lightweight object oriented framework for GNU C.
Loading...
Searching...
No Matches
Objectively

Object oriented framework for C.

Zlib license.

About

Objectively is a cross-platform object oriented framework for the C programming language. Objectively provides rich OO semantics to enable object oriented programming directly in C.

Features

  • Windows, macOS, iOS, Android & Linux cross-platform support
  • Single-parent inheritance with starts-with struct composition
  • Class and instance methods with strongly typed interfaces
  • Automatic class loading and lifecycle management
  • Automatic memory management with reference counting
  • Unicode strings with multibyte character set support
  • Collections for Objects and C types: Array, Dictionary, List, Set and more
  • JSON parsing, marshaling, and JSONPath queries
  • Concurrency: Lock, Condition, Thread, Operation, OperationQueue
  • Networking: URLSession, JSONContext & RESTClient

Class Hierarchy

Browse the class hierarchy to navigate the full API.

Declaring a Type

Every Objectively type consists of three components:

1. The instance struct — starts with the parent type, then the interface pointer, then instance variables:

struct Hello {
Object object; // parent (starts-with = single inheritance)
HelloInterface *interface;
const char *greeting;
};
Object is the root Class of The Objectively Class hierarchy.
Definition Object.h:46

2. The interface struct — starts with the parent interface, then method function pointers:

struct HelloInterface {
ObjectInterface objectInterface;
Hello *(*helloWithGreeting)(const char *greeting);
Hello *(*initWithGreeting)(Hello *self, const char *greeting);
void (*sayHello)(const Hello *self);
};

3. The Class archetype — a single exported function that returns the Class:

OBJECTIVELY_EXPORT Class *_Hello(void);
#define OBJECTIVELY_EXPORT
Definition Types.h:36
The runtime representation of a Class.
Definition Class.h:95

Implementing a Type

#include <stdio.h>
#include <Objectively.h>
#define _Class _Hello
static Hello *helloWithGreeting(const char *greeting) {
return $(alloc(Hello), initWithGreeting, greeting);
}
static Hello *initWithGreeting(Hello *self, const char *greeting) {
self = (Hello *) super(Object, self, init);
if (self) {
self->greeting = greeting ?: "Hello World!";
}
return self;
}
static void sayHello(const Hello *self) {
printf("%s\n", self->greeting);
}
static void initialize(Class *clazz) {
((HelloInterface *) clazz->interface)->helloWithGreeting = helloWithGreeting;
((HelloInterface *) clazz->interface)->initWithGreeting = initWithGreeting;
((HelloInterface *) clazz->interface)->sayHello = sayHello;
}
Class *_Hello(void) {
static Class *clazz;
static Once once;
do_once(&once, {
clazz = _initialize(&(const ClassDef) {
.name = "Hello",
.superclass = _Object(),
.instanceSize = sizeof(Hello),
.interfaceOffset = offsetof(Hello, interface),
.interfaceSize = sizeof(HelloInterface),
});
});
return clazz;
}
#undef _Class
static void initialize(Class *clazz)
Definition Array.c:710
static Array * init(Array *self)
Definition Array.c:420
Class * _initialize(const ClassDef *def)
Initializes the given Class.
Definition Class.c:86
#define alloc(type)
Allocate and initialize and instance of type.
Definition Class.h:176
#define super(type, obj, method,...)
Class * _Object(void)
Definition Object.c:136
Objectively: Ultra-lightweight object oriented framework for GNU C.
long Once
The Once type.
Definition Once.h:37
#define do_once(once, block)
Executes the given block at most one time.
Definition Once.h:43
ClassDefs are passed to _initialize via an archetype to initialize a Class.
Definition Class.h:41
ident interface
The interface of the Class.
Definition Class.h:105

Using a Type

Using your custom type is trivial. Instantiate it like you would any Objectively type.

Hello *hello = $(alloc(Hello), initWithGreeting, "Hello, World!");
$(hello, sayHello);
release(hello);
ident release(ident obj)
Atomically decrement the given Object's reference count. If the resulting reference count is 0,...
Definition Class.c:195

See Hello.h and Hello.c for the full source.

Initialization

There is no explicit setup or teardown with Objectively. To instantiate a type, simply call alloc from anywhere in your program. The first time a type is instantiated, its Class initializer, initialize, is called. Use initialize to setup your interface, override methods, or initialize a library your class wraps. When your application terminates, an optional Class destructor, destroy, is also called.

Invoking an instance method

To invoke an instance method, use the $ macro.

$(condition, waitUntilDate, date);
static bool waitUntilDate(Condition *self, const Date *date)
Definition Condition.c:106
static Date * date(void)
Definition Date.c:98

Invoking a Class method

To invoke a Class method, use the $$ macro.

static Dictionary * dictionary(void)
Definition Dictionary.c:242
Key-value stores.
Definition Dictionary.h:60

Overriding a method

To override a method, overwrite the function pointer from within your Class' initialize method.

((ObjectInterface *) clazz->interface)->dealloc = dealloc;
((ObjectInterface *) clazz->interface)->isEqual = isEqual;
static bool isEqual(const Object *self, const Object *other)
Definition Array.c:145
static void dealloc(Object *self)
Definition Array.c:99

Calling super

To invoke a supertype's method implementation, use the super macro.

Managing memory

Objectively uses reference counting to govern object retention. Newly instantiated Objects have a reference count of 1. To retain a strong reference to an Object, call retain(obj). To relinquish it, call release(obj). Once an Object's reference count reaches 0, it is deallocated. Remember to balance every retain with a release.

Shared instances

A shared instance or singleton pattern can be achieved through Class methods and release-on-destroy.

static *URLSession sharedInstance(void) {
static Once once;
do_once(&once, {
});
}
static void destroy(Class *clazz) {
}
// ...
static void destroy(Class *clazz)
Definition Boole.c:102
static Log * _sharedInstance
Definition Log.c:206
static Log * sharedInstance(void)
Definition Log.c:212
A management context for loading resources via URLs.
Definition URLSession.h:57

Remember to wire up the desctructor in your Class' initialization block. See Once.h for details on do_once.