[plt-scheme] FFI - garbage collection
On Oct 12, Yoav Goldberg wrote:
> > > Hi.
> > > I am wrapping a dll using the v299 ffi.
> > > As a part of my code, I have a c function that returns a pointer to
> > > a structure:
> > > (define-syntax defmshare
> > > (syntax-rules ()
> > > ((defmshare scheme-name libname type ...)
> > > (define scheme-name (get-ffi-obj libname mshare (type ...))))))
> > >
> > > (defmshare MidiNewEv* "MidiNewEv" _fun _short -> _TMidiEv-pointer)
> > (Ugh, if you went all the way to a macro, why not make the macro add
> > the _fun? Otherwise it doesn't do much, and actually looks clearer
> > with the parens.)
> I find it more readable with the _fun and without the parens.. And
> the macro is used just to save some typing..
(Look at the code in the ffi collection.)
> Yes, but unlike C, it is very easy to create these things in Scheme
> without any handle, and so there is no way to free them: (MidiNewEv
> 4).
The exact same thing can be done in C. Just move the paren over.
> > Perhaps the library is meant to be used in a way that you never
> > create these objects unless you send them? This means that
> > another way to organize things is to have some Scheme objects that
> > stand for these TMidiEv objects -- then, you do a wrapper for
> > MidiSendIm that will get one of these Scheme objects, generate a
> > real TMidiEv object, initialize it, and immediately send it over
> > to MidiSendIm.
> This is a possibility. Another option I though of after I sent the
> mail was to use the library function "MidiCopyEv", and wrap
> MidiSendIm so it will be passed a copy instead of the original:
> (let ((origMidiSendIm MidiSendIm))
> (set! MidiSendIm
> (lambda (chan event)
> (origMidiSendIm chan (MidiCopyEv event)))))
>
> This seems very similar (and also quite the opposite?) to what you
> suggested. Which do you think will be more efficiant? Which do you
> think is nicer?
Better to keep it to Scheme values as long as possible. This way, if
you do some extensions, they're easier.
> > One thing you have to be aware of, is that allocation using the
> > Scheme `malloc' goes through the GC by default. I don't think
> > that it will be a good idea to pass such objects to a C library
> > that will try to free them...
> What is the Scheme "malloc", and what does it allocate?
It's the foreign.ss interface to the built-in C malloc (actually, to a
few of them). If you call a foreign function that allocates
something, it will no do it through the GC, so you need the
registration. But, if you use something like (malloc _MidiEv), then
the allocation happens through the GC and will be collected
automatically.
--
((lambda (x) (x x)) (lambda (x) (x x))) Eli Barzilay:
http://www.barzilay.org/ Maze is Life!