[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