[racket] FFI, string, malloc/free

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Sat Jun 15 11:15:03 EDT 2013

With

 (fun _string -> _void)

keep in mind that `_string' means that a Racket-level Unicode string is
converted (by UTF-8 encoding) to a newly allocated array of bytes.
Nothing that you do to with Racket string affects the memory management
of the allocated bytes.

The byte string is allocated as GCable, which means that the bytes can
move or be collected. That works fine as long as the foreign function
is effectively atomic (i.e., no GCs happen between the call and return
of the foreign function).

If the foreign function retains the pointer you give it, then you'll
need to take much more control. Either use `(malloc 'raw ...)' and
`free', or use `(malloc 'atomic-interior ...)' and ensure that the
result remains reachable for as long as its referenced by the foreign
function. Also, use the type

  (fun _pointer -> _void)

for the foreign function, so that the pointer you allocate is passed
through.


At Sat, 15 Jun 2013 08:26:39 -0400, Hendrik Boom wrote:
> On Sat, Jun 15, 2013 at 02:15:04PM +0200, Laurent wrote:
> > On Sat, Jun 15, 2013 at 1:55 PM, Roman Klochkov <kalimehtar at mail.ru> wrote:
> > 
> > > What about
> > >
> > > (define-lib foo (fun _string -> _void))
> > >
> > > (foo "Test")
> > >
> > > ?
> > >
> > > Will be the pointer from string "Test" freed?
> > >
> > 
> > I *think* Racket will garbage collect the "Test" value when it is not used
> > anymore on the Racket side, but it won't know what happens on the ffi C
> > side (hence the "ffi/unsafe").
> > So I think the lib may point to a freed value if you're not cautious.
> > 
> > 
> > > And how to make it retain, if I need to save it on the foreign side?
> > >
> > 
> > You can probably at least simply store it in a global variable. There may
> > be a better way to do it though.
> > For example (not tested) :
> > #lang racket
> > (define dontfreethem '())
> > (define (dontfreeme x)
> >   (set! dontfreethem (cons x dontfreethem))
> >   x)
> > 
> > (foo (dontfreeme "Test"))
> > 
> > Laurent
> 
> But the garbage collector can still move the string when collecting, so 
> protecting it from being freed isn't enough.
> 
> Isn't there some way to declare an object immovable?
> 
> -- hendrik
> 
> 
> > ____________________
> >   Racket Users list:
> >   http://lists.racket-lang.org/users
> 
> ____________________
>   Racket Users list:
>   http://lists.racket-lang.org/users

Posted on the users mailing list.