Code snippets:opaque type

From C

Jump to: navigation, search
/* Shao Miller, Jan-21-2012 */
#define M_ALL_IN_ONE 1

/**** funcject.h */
/*** Types */
typedef struct incompatible_type * fjret_t;
typedef fjret_t fj_f();
typedef fj_f ** fjref_t;
typedef fj_f * fj_t[1];


/**** test.h */
/*** Objects */
extern fjref_t foo;


/**** test.c */
#include <stdio.h>

#if !M_ALL_IN_ONE
#include "funcject.h"
#include "test.h"
#endif /* M_ALL_IN_ONE */

/*** Types */
struct test_funcject;

/*** Function declarations */
static void show_state(struct test_funcject *);
static fj_f test1;
static fj_f test2;
static fj_f test3;

/*** Struct/union definitions */
struct test_funcject {
    /* Handler */
    fj_t func;
    /* Other stuff */
    int x;
    double y;
  };

/*** Objects */
static struct test_funcject my_funcject = { { test1 }, 13, 3.14 };
fjref_t foo = my_funcject.func;

/*** Function definitions */
static void show_state(struct test_funcject * this) {
    printf("We have: %d and %f\n", this->x, this->y);
    return;
  }

/* Actual definition compatible with above declaration */
static fjret_t test1(fj_t fj) {
    struct test_funcject * const this = (void *) fj;

    puts("test1():");
    show_state(this);
    this->func[0] = test2;
    puts("test1() complete.\n");
    return 0;
  }

/* Actual definition compatible with above declaration */
static fjret_t test2(fj_t fj, int x) {
    struct test_funcject * const this = (void *) fj;

    puts("test2():");
    show_state(this);
    this->x = x;
    puts("I just set x");
    show_state(this);
    this->func[0] = test3;
    puts("test2() complete.\n");
    return 0;
  }

/* Actual definition compatible with above declaration */
static fjret_t test3(fj_t fj, double y) {
    struct test_funcject * const this = (void *) fj;

    puts("test3():");
    show_state(this);
    this->y = y;
    puts("I just set y");
    show_state(this);
    this->func[0] = test1;
    puts("test3() complete.\n");
    return 0;
  }


/**** main.c */
#if !M_ALL_IN_ONE
#include "funcject.h"
#include "test.h"
#endif /* M_ALL_IN_ONE */

int main(void) {
    /* Pretend all we know about is 'foo' */
    (*foo)(foo);
    (*foo)(foo, 42);
    (*foo)(foo, 13.42f);
    (*foo)(foo);
    (*foo)(foo, 99);
    (*foo)(foo, 99.99);
    return 0;
  }
Personal tools