[Cffi-devel] Lists of METAOBJECTS and FOREIGN-ALLOC

Willem Rein Oudshoorn woudshoo at xs4all.nl
Tue Apr 29 20:51:04 UTC 2014


Joeish W <joeish80829 at yahoo.com> writes:

> I have this conditional from a cond statement I need to satisfy
>
>
>     ((listp (first args))
>      (c-arr-to-vector-point (first args)))
>
>
> The (first args)  will be this but it should be able to have  an infinite number 
> of (point i j) in it.
>
> (foreign-alloc :pointer :initial-contents  (LIST (POINT 1 2) (POINT 3 4)))


Few points:

0.  My gut feeling is that you have actually on the C++ side:
    vector<Point> and not vector<Point*> so the approach you are taking
    will not work.   However if you are talking about vector<Point*>
    (or you C wrapper takes as type:   Point*[].  The following points
    should guide you.

1.  In my mind, a best practice is that you only call foreign-alloc in
    `translate-to-foreign` method.

2.  You should design a type like `point-vector` with `define-foreign-type`.

3.  The `translate-to-foreign` method should look like:

    (defmethod translate-to-foreign ((lisp-data list) (c-type point-vector))
       ...)

4.  For memory management you should also implement a suitable version of:

     (defmethod free-translated-object (c-data (c-type point-vector) extra-data)
         ...)


However I cannot expand on this right now.  But this should give you
pointers on how to start.  
I strongly recommend reading the CFFI manual including the chapter
describing the example on how to wrap the curl library.

    
>
>
> The thing is that the output of (point i j) is a metaobject
> e.g. #<CV-POINT {10038888E3}> . That is how I have my return for point
> defined. When I need to use foreign-alloc to define an array of point
> I have to  do it like this...
>
>
> (foreign-alloc :pointer :initial-contents  (LIST (c-pointer (POINT 1 2)) (c-pointer (POINT 3 4))))

Or like this:

(foreign-alloc :pointer :initial-contents 
  (mapcar (p) (c-pointer (point (car p) (cdr p))))
 '((1 . 2) (3 . 4) ...))




> (defun vector-point (&rest args)
>   (cond
>     ((fourth args)
>      (error "odd number of args to VECTOR-POINT"))
>     ((null (first args))
>      (%vector-point))
>     ((listp (first args))
>      (%c-arr-to-vector-point (foreign-alloc :pointer :initial-contents (first args))))
>     ((eq :size (second args))
>      (%vector-point-size (first args)))
>     ((and (eq (type-of (first args)) 'std-vector-point) (second args) (not (third args))) 
>      (mem-aref (c-pointer 
>         (%vector-point-to-c-array (first args))) :pointer (second args)))
>     ((and (eq (type-of (first args)) 'std-vector-point) (second args) (third args)) 
>      (mem-aref (c-pointer 
>         (mem-aref (c-pointer 
>                (%vector-point-to-c-array (first args))) :pointer (second args))) 
>            :int (third args)))
>     ((not (eq (type-of (first args)) 'std-vector-point))
>      (error "The value ~a is not of type (STD-VECTOR-POINT)." (first args)))))

I suggest reading up on keyword arguments and optional arguments.  
This is not really understandable.  

Wim Oudshoorn





More information about the cffi-devel mailing list