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