On Wed, Feb 3, 2016 at 10:54 AM, Christoph Höger < christoph.hoeger@tu-berlin.de> wrote: > void g(void* user_data, double t, double const *x, double *g) { > const struct interface_data* data = ((struct interface_data*)user_data); > static long count = 0; > count++; > > /* Wrap the values in fresh big arrays */ > value ml_t = caml_copy_double(t); > value ml_x = caml_ba_alloc_dims(CAML_BA_FLOAT64 | CAML_BA_C_LAYOUT, 1, > (double*)x, data->qs->n); > value ml_g = caml_ba_alloc_dims(CAML_BA_FLOAT64 | CAML_BA_C_LAYOUT, 1, > g, data->qs->mc); > > /* call the OCaml callback */ > caml_callback3(data->g, ml_t, ml_x, ml_g); > } > > Is there anything obvious, I am doing wrong? > ​You need to register [ml_t], [ml_x] and [ml_g​ ] as GC roots. Otherwise if the GC runs in caml_ba_alloc for instance, [ml_t] might ends up containing garbage even before reaching [caml_callback3]. You can use the normal macros for that: void g(...) { CAMLparam0(); CAMLlocal3(ml_t, ml_x, ml_g); ... CAMLreturn0; } ​Note that &(user_data->g) must be a GC root as well. Are you registering &(user_data->g) with the GC in any way? ​ ​ -- Jeremie