void * example
#include <stdio.h> | |
#include <stdlib.h> | |
#include "compute.h" | |
typedef struct { | |
// Material coefficients: | |
double a11, a12, a21, a22; | |
// There can be a lot of variables and big arrays here, this needs | |
// to be passed around by reference. | |
} my_data; | |
void derivs(double x, double y, double *dx, double *dy, void *data) | |
{ | |
my_data *d = data; | |
*dx = d->a11 * x + d->a12 * y; | |
*dy = d->a21 * x + d->a22 * y; | |
} | |
void print_material_parameters(eq d) | |
{ | |
// Access the context: | |
my_data *ctx; | |
get_context(d, &ctx); | |
printf("Material parameters: %f %f %f %f\n", ctx->a11, ctx->a12, | |
ctx->a21, ctx->a22); | |
} | |
int main() | |
{ | |
my_data data1; | |
data1.a11 = 0; | |
data1.a12 = -1; | |
data1.a21 = 1; | |
data1.a22 = 0; | |
my_data data2; | |
data2.a11 = 0; | |
data2.a12 = 1; | |
data2.a21 = 1; | |
data2.a22 = 0; | |
eq d; | |
init(&d); | |
register_func(d, derivs, &data1); | |
run(d, 0, 1, 0.1, 10); | |
print_material_parameters(d); | |
printf("\n"); | |
register_func(d, derivs, &data2); | |
run(d, 0, 1, 0.1, 10); | |
print_material_parameters(d); | |
destroy(&d); | |
return 0; | |
} |
#ifndef _compute_impl_h | |
#define _compute_impl_h | |
#include "compute.h" | |
struct _eq_private { | |
void *data; | |
derivs_pt func; | |
}; | |
#endif |
#include <stdio.h> | |
#include <stdlib.h> | |
#include "compute-impl.h" | |
void init(eq *d) | |
{ | |
*d = malloc(sizeof **d); | |
(*d)->func = NULL; | |
} | |
void register_func(eq d, derivs_pt func, void *data) | |
{ | |
d->func = func; | |
d->data = data; | |
} | |
void get_context(eq d, void *data) | |
{ | |
*(void**)data = d->data; | |
} | |
void run(eq d, double x0, double y0, double dt, double n_steps) | |
{ | |
if (d->func == NULL) { | |
printf("d.func is NULL\n"); | |
abort(); | |
} | |
double x, y, dx, dy, t; | |
int i; | |
x = x0; | |
y = y0; | |
t = 0; | |
for (i=0; i < n_steps; i++) { | |
d->func(x, y, &dx, &dy, d->data); | |
printf("%f %f\n", x, y); | |
x += dx * dt; | |
y += dy * dt; | |
t += dt; | |
} | |
} | |
void destroy(eq *d) | |
{ | |
if (!*d) return; | |
free(*d); | |
} |
#ifndef _compute_h | |
#define _compute_h | |
typedef void (*derivs_pt)(double x, double y, double *dx, double *dy, | |
void *data); | |
/* Definition of the struct is not visible to user code, changes do not affect ABI */ | |
typedef struct _eq_private *eq; | |
void init(eq *d); | |
void register_func(eq d, derivs_pt func, void* data); | |
void get_context(eq d, void *data); | |
void run(eq d, double x0, double y0, double dt, double n_steps); | |
void destroy(eq *d); | |
#endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment