<html><body><div style="color:#000; background-color:#fff; font-family:HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif;font-size:10pt"><div><span>Thanks for getting back to me </span>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?<br></div><div style="display: block;" class="yahoo_quoted"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 10pt;"> <div style="font-family: HelveticaNeue, Helvetica Neue, Helvetica, Arial, Lucida Grande, sans-serif; font-size: 12pt;"> <div dir="ltr"> <font face="Arial" size="2"> On Friday, April 11, 2014 3:53 AM, Martin Simmons <martin@lispworks.com> wrote:<br> </font> </div> <blockquote style="border-left: 2px solid rgb(16, 16, 255); margin-left: 5px; margin-top: 5px; padding-left: 5px;"> <div class="y_msg_container">I think it is better
to avoid garbage collection of foreign objects because it<br clear="none">is too easy to introduce use-after-free errors if you pass the foreign object<br clear="none">to foreign code. Also, finalizers interact poorly with generational GC.<br clear="none"><br clear="none">The simplest way to solve the original problem is to implement a macro that<br clear="none">allocates and frees the object, e.g. with-temporary-mat<br clear="none"><br clear="none">(defmacro with-temporary-mat (mat &body body)<br clear="none"> (let ((m (gensym "mat")))<br clear="none"> `(let ((,m (mat)))<br clear="none"> (unwind-protect<br clear="none"> (let ((,mat ,m))<br clear="none"> ,@body)<br clear="none"> (del-mat ,m)))))<br clear="none"><br clear="none">__Martin<br clear="none"><br clear="none"><div class="yqt5109854115"
id="yqtfd39846"><br clear="none">>>>>> On Fri, 11 Apr 2014 08:59:20 +0200, Stephan Frank said:<br clear="none">> <br clear="none">> Hi Joeish,<br clear="none">> <br clear="none">> have a look at trivial-garbage (<br clear="none">> <a shape="rect" href="http://common-lisp.net/project/trivial-garbage/" target="_blank">http://common-lisp.net/project/trivial-garbage/</a>). This project wraps the<br clear="none">> finalizers of different Lisp implementations with a common interface.<br clear="none">> <br clear="none">> So in your case it is best to wrap the pointer in a Lisp struct and attach<br clear="none">> that the finalizer like this (not tested, so syntax errors may apply). You<br clear="none">> can remove the type annotation of the struct slot if you don't want any<br clear="none">> SBCL-specific code.<br clear="none">> <br clear="none">> (defstruct (cvmatrix (:constructor %make-cvmatrix))<br
clear="none">> (sap (mat) :type sb-sys:system-area-pointer :read-only t))<br clear="none">> <br clear="none">> (defun make-cvmatrix ()<br clear="none">> (let* ((matrix (%make-cvmatrix))<br clear="none">> (sap (cvmatrix-sap matrix)))<br clear="none">> (tg:finalize matrix (lambda (x) (del-mat sap)))<br clear="none">> matrix))<br clear="none">> <br clear="none">> <br clear="none">> Now you create matrices with make-cvmatrix which returns you a cvmatrix<br clear="none">> struct. Whenever this returned struct is garbage collected the finalizer is<br clear="none">> called.<br clear="none">> If you prefer classes to structs, of course a similar approach with<br clear="none">> make-sintance and after methods can be easily implemented.<br clear="none">> <br clear="none">> Regs,<br clear="none">> Stephan<br clear="none">> <br
clear="none">> <br clear="none">> <br clear="none">> 2014-04-10 5:41 GMT+02:00 Joeish W <<a shape="rect" ymailto="mailto:joeish80829@yahoo.com" href="mailto:joeish80829@yahoo.com">joeish80829@yahoo.com</a>>:<br clear="none">> <br clear="none">> > I have Lisp functions that wrap C wrappers for C++ functions that contain<br clear="none">> > a new operator. The C wrappers have to stay the same I can't change those<br clear="none">> > but I was advised to update my method of GC.<br clear="none">> ><br clear="none">> > Here are the C wrappers:<br clear="none">> ><br clear="none">> > Mat* cv_create_Mat() {<br clear="none">> > return new Mat();<br clear="none">> > }<br clear="none">> ><br clear="none">> > void cv_delete_Mat(void* ptr) {<br clear="none">> > delete (~Mat*)ptr;<br clear="none">> > }<br clear="none">> ><br
clear="none">> > Here are the Lisp wrappers for them:<br clear="none">> ><br clear="none">> > (defcfun ("cv_create_Mat" mat) (:pointer mat)<br clear="none">> > "MAT constructor")<br clear="none">> ><br clear="none">> > (defcfun ("cv_delete_Mat" del-mat) :void<br clear="none">> > (ptr :pointer))<br clear="none">> ><br clear="none">> > In a loop, as below, I would normally after calling a MAT function, delete<br clear="none">> > it when I'm done with it manually with DEL-MAT, but I heard there was a<br clear="none">> > better way by actually entering in the DEL-MAT function into Lisps natural<br clear="none">> > GC methods so it would know when it comes across a function with a new it<br clear="none">> > should call delete to get rid of it when it know i'm done with it.. The<br clear="none">> > thing is I could use help to get started. Hopefully a
concrete example of<br clear="none">> > how to do this so I don't have to call DEL-MAT manually<br clear="none">> ><br clear="none">> > (dotimes (n 1000)<br clear="none">> > (setf m (mat))<br clear="none">> > (del-mat m))<br clear="none">> ><br clear="none">> > _______________________________________________<br clear="none">> > Cffi-devel mailing list<br clear="none">> > <a shape="rect" ymailto="mailto:Cffi-devel@common-lisp.net" href="mailto:Cffi-devel@common-lisp.net">Cffi-devel@common-lisp.net</a><br clear="none">> > <a shape="rect" href="http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel" target="_blank">http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel</a><br clear="none">> ><br clear="none">> ><br clear="none">> <br clear="none"></div><br><br></div> </blockquote> </div> </div> </div> </div></body></html>