[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