Closure is a simple interface for stateful callbacks in C.
It can be installed using clib
clib install mobiushorizons/closure_moduleIt has a simple API
closure_t closure_new(void * (*fn)(void * ctx, void * arg), void * ctx);This function creates a closure_t which can be called with closure_call
The function pointer passed to closure_new is of the form
void * callback(void * ctx, void * arg);where ctx refers to the context argument passed to closure_new, which will be the same across calls,
and arg is the void *argument passed to closure_call
void * closure_call(closure_t c, void * arg);Calls the closure passing it both the ctx context argument set up on initialization, and the arg argument.
C Module API (for use with cbuild the C module builder )
closure.t closure.new(void * (*fn)(void * ctx, void * arg), void * ctx);This function creates a closure.t which can be called with closure.call
The function pointer passed to closure.new is of the form
void * callback(void * ctx, void * arg);where ctx refers to the context argument passed to closure.new, which will be the same across calls,
and arg is the void *argument passed to closure.call
void * call(closure_t c, void * arg);Calls the closure passing it both the ctx context argument set up on initialization, and the arg argument.
If you are including this with cbuild the modular C preprocessor, use the
first syntax, otherwise, the generated header and c files are included to work in any normal build system.
/* test-closure.module.c */
package "main";
import closure from "./deps/closure/closure.module.c";
#include <stdio.h>
struct state {
int count;
};
void * callback(void * ctx, void * arg){
if (ctx == NULL) return NULL;
struct state * state = (struct state *)ctx;
state->count++; // increment invocation counter
printf("callback has been called %d times, Message was '%s'\n", state->count, (char*) arg);
return NULL;
}
int main(){
struct state state = {
.count = 0,
};
closure.t cb = closure.new(callback, &state);
closure.call(cb, "Hello World!!");
closure.call(cb, "Lorem");
closure.call(cb, "Ipsum ...");
closure.call(cb, "You Get the picture.");
printf("Our callback was called %d times\n", state.count);
}compile with mpp -m test-closure.module.c, which will produce a test-closure binary in the same directory.
/* test-closure-standard-c.c */
#include "./deps/closure/closure.h"
#include <stdio.h>
struct state {
int count;
};
void * callback(void * ctx, void * arg){
if (ctx == NULL) return NULL;
struct state * state = (struct state *)ctx;
state->count++; // increment invocation counter
printf("callback has been called %d times, Message was '%s'\n", state->count, (char*) arg);
return NULL;
}
int main(){
struct state state = {
.count = 0,
};
closure_t cb = closure_new(callback, &state);
closure_call(cb, "Hello World!!");
closure_call(cb, "Lorem");
closure_call(cb, "Ipsum ...");
closure_call(cb, "You Get the picture.");
printf("Our callback was called %d times\n", state.count);
}compile with cc ./deps/closure/closure.c test-closure-standard-c.c -o test-closure-standard-c;