At Mon, 20 Aug 2012 21:56:40 +0400, Dmitry Pavlov wrote:
> However, it seems that I have a similar problem with a callback
> that fills an array malloc()-ed in the C library, and I am stupid
> enough not to understand why it fails, again.
> Could you please take a look at this:
> 
> int myfunc2 (int length, double *x, int (*filler) (int length, double *arr))
> {
>     double *buf = (double *)malloc(length * sizeof(double));
>     filler(length, buf);
>     memcpy(x, buf, length * sizeof(double));
>     free(buf);
>     return 0;
> }

The problem in this case is that the C code receives a pointer `x' to a
GC-managed object, and the object at that memory moves during the
callback to filler(), so that memcpy(x, ....) copies to the wrong
place.

Assuming that your C code will remain oblivious to GC, you'll have to
change the call to myfunc2() to pass a reference to an object that is
either not GC-managed or won't be moved by a GC (i.e., allocated using
'atomic-interior mode):

 (define (make-f64vector/immobile n)
   (cast (malloc n _double 'atomic-interior)
         _pointer
         (_gcable (_f64vector o n))))

 (define (test2)
    (let ((vec (make-f64vector/immobile 3)))
       ....))


This example illustrates a general problem with foreign functions and
callbacks: since a GC is possible during the callback, you have to pass
the foreign function only references to things that a GC won't move.

____________________
  Racket Users list:
  http://lists.racket-lang.org/users

Reply via email to