[Cffi-devel] Fw: What is the proper way to do GC in CFFI

Joeish W joeish80829 at yahoo.com
Fri Apr 11 15:52:23 UTC 2014


Thanks for getting back to me Stephan, I  like your idea, its what I was advised to do, I think, but do you agree with Martins comment that it could be error prone?

On Friday, April 11, 2014 3:53 AM, Martin Simmons <martin at lispworks.com> wrote:
 
I think it is better to avoid garbage collection of foreign objects because it
>is too easy to introduce use-after-free errors if you pass the foreign object
>to foreign code.  Also, finalizers interact poorly with generational GC.
>
>The simplest way to solve the original problem is to implement a macro that
>allocates and frees the object, e.g. with-temporary-mat
>
>(defmacro with-temporary-mat (mat &body body)
>  (let ((m (gensym "mat")))
>    `(let ((,m (mat)))
>       (unwind-protect
>           (let ((,mat ,m))
>             , at body)
>         (del-mat ,m)))))
>
>__Martin
>
>
>
>>>>>> On Fri, 11 Apr 2014 08:59:20 +0200, Stephan Frank said:
>> 
>> Hi Joeish,
>> 
>> have a look at trivial-garbage (
>> http://common-lisp.net/project/trivial-garbage/). This project wraps the
>> finalizers of different Lisp implementations with a common interface.
>> 
>> So in your case it is best to wrap the pointer in a Lisp struct and attach
>> that the finalizer like this (not tested, so syntax errors may apply). You
>> can remove the type annotation of the struct slot if you don't want any
>> SBCL-specific code.
>> 
>> (defstruct (cvmatrix (:constructor %make-cvmatrix))
>>   (sap (mat) :type sb-sys:system-area-pointer :read-only t))
>> 
>> (defun make-cvmatrix ()
>>   (let* ((matrix (%make-cvmatrix))
>>          (sap (cvmatrix-sap matrix)))
>>     (tg:finalize matrix (lambda (x) (del-mat sap)))
>>     matrix))
>> 
>> 
>> Now you create matrices with make-cvmatrix which returns you a cvmatrix
>> struct. Whenever this returned struct is garbage collected the finalizer is
>> called.
>> If you prefer classes to structs, of course a similar approach with
>> make-sintance and after methods can be easily implemented.
>> 
>> Regs,
>> Stephan
>> 
>> 
>> 
>> 2014-04-10 5:41 GMT+02:00 Joeish W <joeish80829 at yahoo.com>:
>> 
>> > I have Lisp functions that wrap C wrappers for C++ functions that contain
>> > a new operator. The C wrappers have to stay the same I can't change those
>> > but I was advised to update my method of GC.
>> >
>> > Here are the C wrappers:
>> >
>> > Mat* cv_create_Mat() {
>> >     return new Mat();
>> > }
>> >
>> > void cv_delete_Mat(void* ptr) {
>> >     delete (~Mat*)ptr;
>> > }
>> >
>> > Here are the Lisp wrappers for them:
>> >
>> > (defcfun ("cv_create_Mat" mat) (:pointer mat)
>> >   "MAT constructor")
>> >
>> > (defcfun ("cv_delete_Mat" del-mat) :void
>> >   (ptr :pointer))
>> >
>> > In a loop, as below, I would normally after calling a MAT function, delete
>> > it when I'm done with it manually with DEL-MAT, but I heard there was a
>> > better way by actually entering in the DEL-MAT function into Lisps natural
>> > GC methods so it would know when it comes across a function with a new it
>> > should call delete to get rid of it when it know i'm done with it.. The
>> > thing is I could use help to get started.  Hopefully a concrete example of
>> > how to do this so I don't have to call DEL-MAT manually
>> >
>> > (dotimes (n 1000)
>> > (setf m (mat))
>> > (del-mat m))
>> >
>> > _______________________________________________
>> > Cffi-devel mailing list
>> > Cffi-devel at common-lisp.net
>> > http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
>> >
>> >
>> 
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20140411/c8a54777/attachment.html>


More information about the cffi-devel mailing list