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))
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
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
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
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
Stephan, I was needing the output of the code to be a pointer not a struct..should I just use with-foreign-object, or is there a way to output as a pointer in the code you provided. Also I'm getting a " The variable X is defined but never used."..this will be my template for future binding like this so..I'd really like to get this right according to your vision, unless I find it's necessary I,d like to stay away from with macros.
On Friday, April 11, 2014 8:52 AM, Joeish W joeish80829@yahoo.com wrote:
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
Joeish W joeish80829@yahoo.com writes:
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.
As already mentioned before, use the package 'trivial-garbage'.
The cl-git package that wraps the libgit2 C code might be a good example.
The cl-git code tries the handle automatic freeing by the garbage collector, but also allows you to free manually. In addition it keeps track of dependencies, e.g. in cl-git a 'commit' is only valid as long as the 'repository' is open.
It is not much code and might give some inspiration.
Disclaimer, I was quite involved in this bit of cl-git, the project is on github:
https://github.com/russell/cl-git
As an additional question, maybe not well suited for this list. I see you are wrapping the OpenCV code. There are already two other wrappers. So I am curious what are the deficiencies of the existing wrappers that your wrapper tries to solve?
Wim Oudshoorn.
I already figured out a great finalizer, I could just use help on one thing. The below finalizer is for the %mat defcfun below that. How do I update the finalizer below to be for the mat-data defcfun at the bottom of the page. So where do I put the rows cols params, there seems to be no place for them in the defstruct wwhere %mat is called. Any help is appreciated (defstruct (cvmatrix (:constructor %make-cvmatrix)) (sap (%mat) :type sb-sys:system-area-pointer :read-only t)) (defun make-cvmatrix (&optional enable-finalizer) (let* ((matrix (%make-cvmatrix)) (sap (cvmatrix-sap matrix))) (when enable-finalizer (tg:finalize matrix (lambda () (del-mat sap)))) sap))
(defcfun ("cv_create_Mat" %mat) (:pointer mat) "MAT constructor") ;; Mat::Mat(int rows, int cols, int type, void* data) ;; Mat* cv_create_Mat_with_data(int rows, int cols, int type, void* data) (defcfun ("cv_create_Mat_with_data" mat-data) (:pointer mat) (rows :int) (cols :int) (type :int) (data :pointer))
On Sunday, April 13, 2014 12:28 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
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.
As already mentioned before, use the package 'trivial-garbage'.
The cl-git package that wraps the libgit2 C code might be a good example.
The cl-git code tries the handle automatic freeing by the garbage collector, but also allows you to free manually. In addition it keeps track of dependencies, e.g. in cl-git a 'commit' is only valid as long as the 'repository' is open.
It is not much code and might give some inspiration.
Disclaimer, I was quite involved in this bit of cl-git, the project is on github:
https://github.com/russell/cl-git
As an additional question, maybe not well suited for this list. I see you are wrapping the OpenCV code. There are already two other wrappers. So I am curious what are the deficiencies of the existing wrappers that your wrapper tries to solve?
Wim Oudshoorn.
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W joeish80829@yahoo.com writes:
I already figured out a great finalizer, I could just use help on one thing. The below finalizer is for the %mat defcfun below that. How do I update the finalizer below to be for the mat-data defcfun at the bottom of the page. So where do I put the rows cols params, there seems to be no place for them in the defstruct wwhere %mat is called. Any help is appreciated
Hm, I feel this is not the right way to approach this. However, there is a bug in your finalize logic.
1. If you call make-cvmatrix with enable-finalizer true you attach a finalize on the new instance of cvmatrix. 2. However you return the SAP. 3. As a consequence the cvmatrix instance can be immediately garbage collected, even if the returned SAP still has references to it.
(defstruct (cvmatrix (:constructor %make-cvmatrix)) (sap (%mat) :type sb-sys:system-area-pointer :read-only t)) (defun make-cvmatrix (&optional enable-finalizer) (let* ((matrix (%make-cvmatrix)) (sap (cvmatrix-sap matrix))) (when enable-finalizer (tg:finalize matrix (lambda () (del-mat sap)))) sap))
I do not think that this is what you want.
Two remarks for future improvement:
1. You use sb-sys:system-area-pointer as type, and this will tie you to SBCL. There is no reason for that.
2. You should read up on `translate-to-foreign' and `translate-from-foreign' in the cffi documentation. It will really help to make the code simpler, cleaner and more robust.
If I have more time I might give some more detailed suggestions. But I hope this helps a bit.
Wim Oudshoorn.
If you get some free time I would love to see a concrete example, but I do appreciate you time so far and don't want to put you out in any way.. I'm building a big library and the better I can make each individual component the better
On Sunday, April 13, 2014 8:26 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
I already figured out a great finalizer, I could just use help on one thing. The below finalizer is for the %mat defcfun below that. How do I update the finalizer below to be for the mat-data defcfun at the bottom of the page. So where do I put the rows cols params, there seems to be no place for them in the defstruct wwhere %mat is called. Any help is appreciated
Hm, I feel this is not the right way to approach this. However, there is a bug in your finalize logic.
- If you call make-cvmatrix with enable-finalizer true you attach a
finalize on the new instance of cvmatrix. 2. However you return the SAP. 3. As a consequence the cvmatrix instance can be immediately garbage collected, even if the returned SAP still has references to it.
(defstruct (cvmatrix (:constructor %make-cvmatrix)) (sap (%mat) :type sb-sys:system-area-pointer :read-only t)) (defun make-cvmatrix (&optional enable-finalizer) (let* ((matrix (%make-cvmatrix)) (sap (cvmatrix-sap matrix))) (when enable-finalizer (tg:finalize matrix (lambda () (del-mat sap)))) sap))
I do not think that this is what you want.
Two remarks for future improvement:
- You use sb-sys:system-area-pointer as type, and this will tie you to
SBCL. There is no reason for that.
- You should read up on `translate-to-foreign' and
`translate-from-foreign' in the cffi documentation. It will really help to make the code simpler, cleaner and more robust.
If I have more time I might give some more detailed suggestions. But I hope this helps a bit.
Wim Oudshoorn.
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W joeish80829@yahoo.com writes:
If you get some free time I would love to see a concrete example, but I do appreciate you time so far and don't want to put you out in any way.. I'm building a big library and the better I can make each individual component the better
Here are some ideas on how I would start to approach this. However, I am still curious what your motivation is of making your bindings to OpenCV?
Note the following is from memory and not tested but I think you are better of with something along the following lines:
;;; UNTESTED CODE, LOOK AT REFERENCE MANUAL FOR WHAT I MEAN ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;; Define the Bridge between the C-type and Lisp type
;;;; Define the C-type
(define-foreign-type cv-matrix-type () nil (:actual-type :pointer) (:simple-parser %cv-matrix))
;;;; Define the lisp type
(defstruct cvmatrix (sap))
;;;; Define the translation between the lisp and C world
(defmethod translate-to-foreign ((cvmatrix cvmatrix) (type cv-matrix-type)) (declare (ignore type)) (cvmatrix-sap cvmatrix))
(defmethod translate-from-foreign (value (type cv-matrix-type)) (make-cvmatrix :sap value))
;;;; Define the functions
(defcfun ("cv_create_Mat" %mat) %cv-matrix)
(defcfun ("cv_create_Mat_with_data" mat-data) %cv-matrix (rows :int) (cols :int) (type :int) (data :pointer)) ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Now of course you want to change the :pointer in the definition of %cv-matrix to a type lik %data or something similar.
If you do that you can define translation methods on %data so you can specify a lisp vector, list or array.
Also I would personally change the names of the functions `mat-data' and `%mat'. They do not really say what they do.
Now for including garbage collection. This depends on how you want your wrapper to behave and on how the OpenCV library handles the memory management of the matrices.
But that is something for another post.
Kind regards, Wim Oudshoorn
If you get some free time I would love to see a concrete example, but I do appreciate you time so far and don't want to put you out in any way.. I'm building a big library and the better I can make each individual component the better
On Sunday, April 13, 2014 8:26 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
I already figured out a great finalizer, I could just use help on one thing. The below finalizer is for the %mat defcfun below that. How do I update the finalizer below to be for the mat-data defcfun at the bottom of the page. So where do I put the rows cols params, there seems to be no place for them in the defstruct wwhere %mat is called. Any help is appreciated
Hm, I feel this is not the right way to approach this. However, there is a bug in your finalize logic.
- If you call make-cvmatrix with enable-finalizer true you attach a
finalize on the new instance of cvmatrix. 2. However you return the SAP. 3. As a consequence the cvmatrix instance can be immediately garbage collected, even if the returned SAP still has references to it.
(defstruct (cvmatrix (:constructor %make-cvmatrix)) (sap (%mat) :type sb-sys:system-area-pointer :read-only t)) (defun make-cvmatrix (&optional enable-finalizer) (let* ((matrix (%make-cvmatrix)) (sap (cvmatrix-sap matrix))) (when enable-finalizer (tg:finalize matrix (lambda () (del-mat sap)))) sap))
I do not think that this is what you want.
Two remarks for future improvement:
- You use sb-sys:system-area-pointer as type, and this will tie you to
SBCL. There is no reason for that.
- You should read up on `translate-to-foreign' and
`translate-from-foreign' in the cffi documentation. It will really help to make the code simpler, cleaner and more robust.
If I have more time I might give some more detailed suggestions. But I hope this helps a bit.
Wim Oudshoorn.
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel