Joeish W | 20 Apr 13:55 2014
Picon

Help perfecting my GC finalizer/constructor

Thanks for your replies to my question, I was planning to go the trivial-garbage route and someone from CFFI-DEVEL kindly gave me this code to do GC automatically using my mat and del-mat functions

 (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))

When I run the make-cvmatrix function to create a matrix  it outputs a struct instead of a pointer like i needed. I changed the last line of the make-cvmatrix function to be "sap"  as below:

    (tg:finalize matrix (lambda (x) (del-mat sap)))
    sap))

...and it appears to run poorly with only major variations in my ram levels which i suppose is just a result of lisps GC in process.
Since I'm new to GC w/ trivial-garbage, I was hoping someone can verify first that the change to sap was an ok move.

I was hoping someone could edit my code so I have a good example of Lisp GC with TG to work from and if I write a defcfun for this C wrapper :

Mat* cv_create_Mat_typed(int rows, int cols, int type) {
    return new Mat(rows, cols, type);
}

eg:


(defcfun ("cv_create_Mat_typed" mat-typed)  (:pointer mat)
  "MAT constructor with a row, column and type parameter."
  (rows :int)
  (cols :int)
  (type :int))

show me where the rows cols type params get placed in an edited finalizer/constructor above..I would definately appreciate greatly:), concrete examples using the code I posted.

_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Cyrus Harmon | 18 Apr 20:01 2014

FSBV question


So I’ve been trying to get FSBV working on ABCL and I’ve run into a problem with returning structs. The
problem is that we allocate memory on the stack for the return struct, successfully call the foreign
function, writing the return value into the appropriate place, then we free the memory and return a
pointer to the now defunct memory location.

I’m curious as to how this is supposed to work in other implementations. It obviously does work in, at
least, SBCL, so I must be doing something wrong. But looking at the ffcall-body-libffi function it looks
like we setup the foreign memory for RESULT in with-foreign-objects and then if we have a
translatable-foreign-type, we return RESULT, which of course gets freed by with-foreign-objects.
What am I missing here?

thanks,

Cyrus

(defun ffcall-body-libffi
    (function symbols return-type argument-types &optional pointerp (abi :default-abi))
  "A body of foreign-funcall calling the libffi function #'call (ffi_call)."
  (let ((number-of-arguments (length argument-types)))
    `(with-foreign-objects
         ((argvalues :pointer ,number-of-arguments)
          , <at> (unless (eql return-type :void)
              `((result ',return-type))))
       (loop :for arg :in (list , <at> symbols)
             :for count :from 0
             :do (setf (mem-aref argvalues :pointer count) arg))
       (call
        (prepare-function ,function ',return-type ',argument-types ',abi)
        ,(if pointerp
             function
             `(foreign-symbol-pointer ,function))
        ,(if (eql return-type :void) '(null-pointer) 'result)
        argvalues)
       ,(if (eql return-type :void)
            '(values)
            (if (typep (parse-type return-type) 'translatable-foreign-type)
                ;; just return the pointer so that expand-from-foreign
                ;; can apply translate-from-foreign
                'result
                ;; built-in types won't be translated by
                ;; expand-from-foreign, we have to do it here
                `(mem-aref result ',return-type))))))
Cyrus Harmon | 16 Apr 01:56 2014

CFFI ABCL bug?


When compiling new-ish CFFI with ABCL, I get a warning that *function-call-encoding* is not defined:

(defun make-function-pointer (pointer convention)
  (apply
   #'jnew
   (if *jna-4.0.0-or-later-p*
       (private-jconstructor "com.sun.jna.Function"
                             "com.sun.jna.Pointer" "int" "java.lang.String")
       (private-jconstructor "com.sun.jna.Function"
                             "com.sun.jna.Pointer" "int"))
   pointer
   (jfield "com.sun.jna.Function"
           (convert-calling-convention convention))
   (when *jna-4.0.0-or-later-p*
     (list *function-call-encoding*))))

Similarly, there’s a defparameter nearby:

(defparameter *jna-string-encoding* "UTF-8"
  "Encoding for conversion between Java and native strings that occurs within JNA.

Used with jna-4.0.0 or later.”)

that doesn’t seem to be used anywhere. Should these two be referring to the same thing?

thanks,

Cyrus
Joeish W | 13 Apr 22:27 2014
Picon

possible cffi bug

I have these 2  wrappers for the C++ vector class and I wrap both in CFFI the same way, and call them the same way but I'm getting unhandled memory fault errors when using my wrapper for the carraytovectorm, The only difference being, using the carraytovectorp as an example of all my other carraytovector type c wrappers that are written the same way, is that when I initialize the Point class to pass to the carraytovectorp I can do it like this:

Point* m, n, o;
vector_Point* v = std_carrayTovectorp(m, 3);

and it works but when I attempt to do the same thing with carrayvectorm like so:

Mat* m, n, o;
vector_Mat* v = std_carrayTovectorm(m, 3);

I get a segmentation fault error in C

This works in both though.

Point m, n, o;
vector_Point* v = std_carrayTovectorp(&m, 3);


If you think this might be a bug too..I can forward any other info needed to debug..I just tried to keep this post light so it wouldn't seem daunting:)




vector_Mat* std_carrayTovectorm(Mat* a, size_t len) {
vector<Mat>* v = new vector<Mat>;
for(size_t i = 0; i < len; i++)
v->push_back(a[i]);
return v;
}
vector_Point* std_carrayTovectorp(Point* a, size_t len) {
    vector<Point>* v = new vector<Point>;
    for(size_t i = 0; i < len; i++)
        v->push_back(a[i]);
    return v;
}
_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 10 Apr 05:41 2014
Picon

What is the proper way to do GC in CFFI

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
Joeish W | 6 Apr 11:03 2014
Picon

"The value is not of type SB-SYS:SYSTEM-AREA-POINTER." when creating 2d array

I'm getting this this Error:

The value
  (FOREIGN-ALLOC :POINTER :INITIAL-ELEMENT
                 (POINT (UNIFORM RNG X-1 X-2)
                        (UNIFORM RNG Y-1 Y-2)))
is not of type
  SB-SYS:SYSTEM-AREA-POINTER.
   [Condition of type TYPE-ERROR]

My array is below, I simplified the array elements to (cffi:null-pointer)  I've been trying everything I can to create a 2d array of pointers. But its all  been coming down to this error: If anyone can help with this I'd be very appreciative.:)

(defvar *2d-array* #2A((


(foreign-alloc :pointer :initial-element (null-pointer))

(foreign-alloc :pointer :initial-element (null-pointer)))

((foreign-alloc :pointer :initial-element (null-pointer))

(foreign-alloc :pointer :initial-element (null-pointer)))))

(foreign-alloc :pointer
               :initial-contents (make-array (reduce #'* (array-dimensions *2d-array*))
                                             :displaced-to *2d-array*))

_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 4 Apr 16:28 2014
Picon

What's the best way to convert c+ classes into Lisp

I have a bunch or C wrappers for C++ OpenCV code I'm writing and I was hoping someone could show me how the best way would be in CFFI to write theses functions.  They're from a C++ class
the OpenCV Point_ class defined here http://docs.opencv.org/modules/core/doc/basic_structures.html?highlight=assignto#Point_

Here are the functions below. So far I'm making the top 2 functions point0 and point2 use the same name "point" with this function:

(defun point (&optional (x nil) (y nil))
       (cond ((eq (or x y) nil)
          (point0))
         ((and x y)
          (point2 x y))
         (t nil)))
 
but I also have functions  to retrieve the x and y coordinates of a point that belong to the same class. I call those point-x and point-y..I was hoping someone could write me up the best way on how to use these Point_ class wrappers . Is it with defclass or define-foreign-type or am I already doing a good job? I could use this info in making all my other class wrappers correctly.


;; Point* cv_create_Point(int x, int y) 
(defcfun ("cv_create_Point" point0) (:pointer point)
  "Point constructor")
 
 
;; Point* cv_create_Point(int x, int y) 
(defcfun ("cv_create_Point2" point2) (:pointer point)
  "Point constructor"
  (x :int)
  (y :int))
 
;; _Tp x, y
;; int cv_Point_getX(Point* self) 
(defcfun ("cv_Point_getX" point-x) :int 
  "Retrieves X coordinate of a point"
  (self (:pointer point)))
 
 
;; _Tp x, y
;; int cv_Point_getY(Point* self)
(defcfun ("cv_Point_getY" point-y) :int 
  "Retrieves y coordinate of a point"
  (self (:pointer point)))

_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 1 Apr 08:49 2014
Picon

Wrapping a C wrapper for OpenCV's vector<Mat>

Here is the C wrapper for vector<Mat> which is just a typename for a C++ vector:

vector_Mat* std_carrayTovectorm(Mat* a, size_t len) {
    vector<Mat>* v = new vector<Mat>;
    for(size_t i = 0; i < len; i++)
        v->push_back(a[i]);
    return v;
}

Here is my wrapper in CFFI:

;; vector_Mat*
(defctype vector-mat :pointer)

(defcfun ("std_carrayTovectorm" %c-arr-to-vector-mat) (:pointer vector-mat)
  (a (:pointer mat))
  (len :unsigned-int))

When I use it as below I get "unhandled memory fault error",  If anyone can check my work I would be much appreciative. I can post my mat-value wrapper if necessary. It works fine though.


(%c-arr-to-vector-mat (foreign-alloc :pointer :initial-contents(list  (mat-value 4 4 +32s+ (scalar 1 2 3)) (mat-value 4 4 +32s+ (scalar 1 2 3)))) 1)
_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 1 Apr 07:38 2014
Picon

How do I covert this 2D array to CFFI

I'm trying to convert this   declaration of an array of points to CFFI but I'm getting unhandled memory fault errors Directly below this C declaration is a tree of foreign-alloc functions I used to create this I'm hoping someone can check my work and tell me if it is my declaration that's the problem

Point pt[2][3];
    pt[0][0].x = rng.uniform(x_1, x_2);
    pt[0][0].y = rng.uniform(y_1, y_2);
    pt[0][1].x = rng.uniform(x_1, x_2);
    pt[0][1].y = rng.uniform(y_1, y_2);
    pt[0][2].x = rng.uniform(x_1, x_2);
    pt[0][2].y = rng.uniform(y_1, y_2);
    pt[1][0].x = rng.uniform(x_1, x_2);
    pt[1][0].y = rng.uniform(y_1, y_2);
    pt[1][1].x = rng.uniform(x_1, x_2);
    pt[1][1].y = rng.uniform(y_1, y_2);
    pt[1][2].x = rng.uniform(x_1, x_2);
    pt[1][2].y = rng.uniform(y_1, y_2);

    const Point* ppt[2] = {pt[0], pt[1]};


(foreign-array-alloc #2A((501 10) (255 10) (501 255) (10 501)) '(:array :int 4 2)))


(d a (foreign-alloc :pointer :count 2 :initial-contents

(list
                           
(foreign-alloc :pointer :count 3 :initial-contents

(list
                                                   (foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2)))

(foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2)))

(foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2)))))


(foreign-alloc :pointer :count 3 :initial-contents

(list
                                                   (foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2)))

(foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2)))

(foreign-alloc :pointer :initial-element
                                                   (point (uniform rng x-1 x-2) (uniform rng y-1 y-2))))))))



Here is how I have point defined it works as intended. The uniform function works well in the point so I didn't post but will if necessary

;; Point* cv_create_Point(int x, int y) 
(defcfun ("cv_create_Point2" point2) (:pointer point)
  "Point constructor"
  (x :int)
  (y :int))
 

_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 30 Mar 17:14 2014
Picon

Re: Fw: Casting variables and functions

I was just wondering why cffi doesn't do automatic conversions.  Since casting is used so much in c I  think it would do automatic conversions...Do experts in CFFI normally use this approach,  do they cast on the Lisp side or use another approach..I'd like to start learning the best way to do things
On , Joeish W <joeish80829 <at> yahoo.com> wrote:
On Sunday, March 30, 2014 7:53 AM, Joeish W <joeish80829 <at> yahoo.com> wrote:
I was just wondering why cffi doesn't do automatic conversions.  Since casting is used so much in c I  think it would do automatic conversions...Do experts in CFFI normally use this approach,  do they cast on the Lisp side or use another approach..I'd like to start learning the best way to do things
On Sunday, March 30, 2014 7:45 AM, Stelian Ionescu <sionescu <at> cddr.org> wrote:
On Sun, 2014-03-30 at 07:18 -0700, Joeish W wrote:
> Thanks for getting back to me., I really appreciate it

> Using coerce  though I'm already casting it to a float on the lisp
> side...I was wondering if I can cast a 4 to a float with CFFI and have
> the output be a 4.0f0 like it works in C...without doing anything on
> the Lisp side

CFFI doesn't do automatic coercions, but you can do it with a custom
type:

(define-foreign-type float+int () ()
  (:actual-type :float)
  (:simple-parser float+int))

(defmethod expand-to-foreign (value (type float+int))
  `(coerce ,value 'float))

(with-foreign-object (val :float)
  (setf (mem-ref val 'float+int) 4)
  (mem-ref val :float))


--
Stelian Ionescu a.k.a. fe[nl]ix
Quidquid latine dictum sit, altum videtur.






_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W | 30 Mar 17:11 2014
Picon

writing documentation for CFFI functions

Which is the better way do write documentation for functions for  a CFFI library

like this?

C++: int RNG::uniform(int a, int b)

Common Lisp: (UNIFORM-D (RNG (:POINTER RNG)) (A :DOUBLE) (B :DOUBLE)) => :DOUBLE

or like this without the parenthesis

C++: float RNG::uniform(float a, float b)

Common Lisp: (UNIFORM-F (RNG :POINTER RNG) A :FLOAT B :FLOAT) => :FLOAT

_______________________________________________
Cffi-devel mailing list
Cffi-devel <at> common-lisp.net
http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel

Gmane