[plt-scheme] FFI - garbage collection
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)
and I also have a wrapper function to initialize the returned struct
to some default values:
(provide (rename MidiNewEv midi-new-ev))
(define MidiNewEv ;; make sure chan/port/date are initialized to a default
(lambda (type)
(let ((ev (MidiNewEv* type)))
(chan! ev 0)
(port! ev 0)
(date! ev 0)
ev)))
I want to make sure the memory allocated by the "MidiNewEv" function
will be freed by GC, and from what I understand, I need to use
"register-finalizaer", like so:
(defmshare MidiFreeEv "MidiFreeEv" _fun _TMidiEv-pointer -> _TMidiEv-pointer)
(define MidiNewEv ;; make sure chan/port/date are initialized to a default
(lambda (type)
(let ((ev (MidiNewEv* type)))
(chan! ev 0)
(port! ev 0)
(date! ev 0)
(register-finalizer ev MidiFreeEv)
ev)))
I hope I got it right until now, let me know if I got something wrong.
But now comes the trickey part.
There is another C function:
(defmshare MidiSendIm "MidiSendIm" _fun _short _TMidiEv-pointer -> _void)
Which FREES any _TMidiEv-pointer passed to it.
As far as I understand this is a problem, since that pointer is still
registered with the finalizer for GC!
How can I fix this? Is there a way to "un-register" a finalizer, so
that I could do something like:
(define GoodMidiSendIm
(lambda (n ev)
(unregister-finalizer ev) (MidiSendIm n ev)))
??
Thanks,
Yoav