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@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)) ,@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@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@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel