Skip to content

Instantly share code, notes, and snippets.

@mattn
Created May 13, 2010 05:02
Show Gist options
  • Save mattn/399514 to your computer and use it in GitHub Desktop.
Save mattn/399514 to your computer and use it in GitHub Desktop.
countup closure in C
// gcc -o closure-counter closure-counter.c -lffi
#include <stddef.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <ffi.h>
int
main(int argc, char **argv) {
ffi_cif cif;
typedef struct { int count; } count_info_t;
typedef int (*countup_func_t)();
void countup_func(ffi_cif *cif, void *ret, void **args, void *user_data) {
count_info_t* ci = (count_info_t*) user_data;
*(int*)ret = ++ci->count;
};
typedef struct _countup_closure_t {
ffi_closure clos;
ffi_cif cif;
countup_func_t countup;
} countup_closure_t;
countup_closure_t* create_counter(int count) {
void *codeloc;
count_info_t* ci;
countup_closure_t* cct;
cct = (countup_closure_t*) ffi_closure_alloc(sizeof(countup_closure_t)+sizeof(int), &codeloc);
if (!cct) return NULL;
cct->countup = codeloc;
cct->cif = cif;
ci = (count_info_t*) malloc(sizeof(count_info_t));
ci->count = (int) count;
ffi_prep_closure_loc(&cct->clos, &cct->cif, countup_func, (void*)ci, codeloc);
return cct;
}
void destroy_counter(countup_closure_t *cct) {
free(cct->clos.user_data);
ffi_closure_free(cct);
}
countup_closure_t* counter1;
countup_closure_t* counter2;
countup_closure_t* counter3;
// initialize
ffi_prep_cif(&cif, FFI_DEFAULT_ABI, 0, &ffi_type_sint, NULL);
// create closure
counter1 = create_counter(1);
counter2 = create_counter(3);
counter3 = create_counter(5);
// invoke...
printf("counter1() = %d\n", counter1->countup()); // 2
printf("counter2() = %d\n", counter2->countup()); // 4
printf("counter3() = %d\n", counter3->countup()); // 6
printf("counter1() = %d\n", counter1->countup()); // 3
printf("counter2() = %d\n", counter2->countup()); // 5
printf("counter3() = %d\n", counter3->countup()); // 7
// destroy counter
destroy_counter(counter1);
destroy_counter(counter2);
destroy_counter(counter3);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment