[EMAIL PROTECTED] (James A. Crippen) writes:
> I have some Alien objects that I'd like to have finalized. Here's
> some example code.
>
> (use-package :ALIEN)
> (use-package :C-CALL)
> (def-alien-type attr-t unsigned-long)
>
> (defun foo ()
> (let ((an-attr (make-alien attr-t)))
> (do-something-to (deref an-attr))
> an-attr))
>
> (defun bar (attr)
> (declare (type (alien (* attr-t)) attr))
> (do-something-different-to (deref attr)))
>
> (bar (foo))
>
> Now with all this I'd like to add a finalizer inside BAR which will
> clean up ATTR by calling FREE-ALIEN on it. Something like this:
>
> (defun bar (attr)
> (declare (type (alien (* attr-t)) attr))
> (unwind-protect
> (do-something-different-to (deref attr))
> (ext:finalize attr #'finalize-attr-t)))
>
> For EXT:FINALIZE I need a function that knows what to do, so I thought
> I'd write one like:
>
> (defun finalize-attr-t (attr)
> (declare (type (alien (* attr-t)) attr))
> (free-alien (deref attr)))
>
> But reading in the user manual (cmu-user.dvi) section '2.5.3
> Finalization' I see
>
> "/function/ is called with no arguments when /object/ is reclaimed.
> Normally /function/ will be a closure over the underlying state that
> needs to be freed, e.g. the unix file descriptor in the fd-stream
> case."
>
> So the Obvious Solution is right out. I can't just expect to be
> passed the object (or a reference to it) into my finalization
> function. How exactly am I supposed to make a closure over 'the
> underlying state'? And how am I supposed to get at this 'underlying
> state' without maintaining a reference to the object itself? I'm
> confused.
This confused me, too. What you want to do is wrap your alien type in
a lisp type, and then finalize the lisp type by deallocating the alien
type:
(defstruct (thing (:constructor %make-thing))
alien-thing)
(defun make-thing ()
(let* ((alien-thing (allocate-alien-thing))
(thing (%make-thing :alien-thing alien-thing)))
(finalize thing #'(lambda ()
(deallocate-alien-thing alien-thing)))))
The trick is not to close over the thing you're finalizing or it will
never be called.
> On a related note, why can't the FUNCTION argument to EXT:FINALIZE
> take one argument that is the object (or a reference to it) being
> finalized? Is this impossible? It would make it much easier for the
> programmer (or for me at least)...
The thing that you're finalizing has already been deallocated by the
time your function is called (that's how the function that calls it
knows to call it) so it can't be passed in.
HTH,
cbb
>
> 'james
>
> --
> James A. Crippen <[EMAIL PROTECTED]> ,-./-. Anchorage, Alaska,
> Lambda Unlimited: Recursion 'R' Us | |/ | USA, 61.20939N, -149.767W
> Y = \f.(\x.f(xx)) (\x.f(xx)) | |\ | Earth, Sol System,
> Y(F) = F(Y(F)) \_,-_/ Milky Way.
>
--
8:15pm up 88 days, 23:03, 1 user, load average: 0.00, 0.05, 0.04