[cffi-devel] [cffi] FSBV (#2)

Liam Healy lhealy at common-lisp.net
Mon Feb 20 16:40:32 UTC 2012


I'm not sure how to address Ryan's case (what I identified as (1)).  I am
(effectively) scrapping the changes I have made by redefining defmethod
aggregatep ((type foreign-pointer-type)) to give nil, because I found
having it T seriously broke GSLL.  I acknowledge your points and Ryan's in
his last email but I don't understand pointers and aggregates and
structures in C and how they should map to CL enough to understand what to
do.  Any thoughts appreciated (Luis? anyone?).

Liam


On Mon, Feb 20, 2012 at 10:38 AM, Martin Simmons <martin at lispworks.com>wrote:

> This looks wrong to me -- a pointer is not an aggregate type.  Also, I
> think
> your test-new-ptr-ref and test-generic-ptr-ref tests are bogus because the
> type in mem-aref doesn't match the type of ptr.
>
> Have you tried it with a struct containing 20 bytes?  Testing it with an
> array
> of two 4 byte structs leads to confusion about the size of a pointer v.s.
> the
> size of one struct v.s. the size of the array.
>
> In fact, I don't understand what mem-aref is supposed to do for an
> aggregate
> type.  Making it return a pointer to the first byte of the aggregate is
> inconsistent with how it treats other types and IMHO leads to the current
> confusion.
>
> __Martin
>
>
>
> >>>>> On Sat, 18 Feb 2012 12:53:17 -0500, Liam Healy said:
> >
> > The new syntax is as follows.  If you want the structure itself, use
> > (:struct foo).  If you want a pointer to it, use (:pointer (:struct
> > foo)).   The latter should be identical to the old style bare struct
> > specification, except for the annoying deprecation warning, of course.
> >
> > The issues I can identify, with their resolutions:
> >
> > 1) Using mem-aref with the (:pointer (:struct ...)) spec gives the wrong
> > pointer.
> >
> > I have fixed an error which should now return the correct pointer for an
> > offset of 0.  For an offset of 1, it returns the base pointer +8 bytes,
> > which is not what the old style gives (+ 4 bytes), but it seems to me
> > correct, as I understand the index to refer to the number of whole
> > structures.   Pull ee90bfd517 and try.
> >
> > 2) The plist form representing the structure is not desirable.
> >
> > You can have any CL representation of the structure you like; you need to
> > define a method cffi:translate-from-foreign for your type class.  You are
> > getting the default, a plist translation, because no such method is
> > defined.   See for example how I translate complex
> > numbers<
> http://repo.or.cz/w/antik.git/blob/1ee407c69525b84b441f8cf7b48ac590e78bd635:/foreign-array/complex-types.lisp#l50
> >to
> > CL complex numbers.  You can even return a pointer if you want, but
> > this
> > probably isn't the specification to use if you want the pointer.
> >
> >
> > On Mon, Feb 13, 2012 at 10:22 AM, Ryan Pavlik <
> >
> reply+i-1614209-ba246666762196459413560690eb7d3a39c7c7ee-838019 at reply.github.com
> > > wrote:
> >
> > > I've pulled the latest and it appears the semantics have changed for
> > > mem-aref, but there is still no way to get the old behavior.  Here is a
> > > complete example, though it doesn't use the test system definitions
> because
> > > actual foreign calls and definitions aren't really the problem:
> > >
> > > ```
> > > (asdf:load-system :cffi)
> > >
> > > (cffi:defcstruct my-struct
> > >  (x :short)
> > >  (y :short))
> > >
> > > (defun test-old-ref ()
> > >  (declare (notinline cffi:mem-ref cffi:mem-aref))
> > >  (cffi:with-foreign-object (ptr '(:struct my-struct) 2)
> > >    (format t "~&Old-ref style:~%ptr : ~A~%aref: ~A~%"
> > >            ptr (cffi:mem-aref ptr 'my-struct 1))))
> > >
> > > (defun test-new-ref ()
> > >  (cffi:with-foreign-object (ptr '(:struct my-struct) 2)
> > >    (format t "~&New-ref style:~%ptr : ~A~%aref: ~A~%"
> > >           ptr
> > >           (cffi:mem-aref ptr '(:struct my-struct) 1))))
> > >
> > > (defun test-new-ptr-ref ()
> > >  (cffi:with-foreign-object (ptr '(:struct my-struct) 2)
> > >    (format t "~&New-ref with :pointer style:~%ptr : ~A~%aref: ~A~%"
> > >           ptr
> > >           (cffi:mem-aref ptr '(:pointer (:struct my-struct)) 1))))
> > >
> > > (progn
> > >  (test-old-ref)
> > >  (test-new-ref)
> > >  (test-new-ptr-ref))
> > > ```
> > >
> > > The output I get, sans style-warnings about bare structs:
> > >
> > > ```
> > > Old-ref style:
> > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFCFFF0)
> > > aref: #.(SB-SYS:INT-SAP #X7FFFEEFCFFF4)
> > > New-ref style:
> > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFCFFF0)
> > > aref: (Y 0 X 0)
> > > New-ref with :pointer style:
> > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFCFFF0)
> > > aref: #.(SB-SYS:INT-SAP #X00000000)
> > > ```
> > >
> > > Note that in the first example, with the original semantics, if you
> > > mem-aref a pointer to an array of `my-struct`, you get a pointer to the
> > > array element.  In the new style, with `(:struct my-struct)`, you get
> the
> > > values parsed into a list, which is not particularly useful; it
> conses, and
> > > you almost certainly have to re-parse a possibly long list for a single
> > > element.  In the new style with `:pointer`, it appears to dereference
> the
> > > Nth element in an *array of pointers to my-struct*, which is not at all
> > > what we want.
> > >
> > > The latter differs from the behavior before I updated, which seemed to
> > > return a *pointer* to the Nth element in an array-of-pointers.  None
> of the
> > > above are like the old behavior.
> > >
> > > ---
> > > Reply to this email directly or view it on GitHub:
> > > https://github.com/cffi/cffi/pull/2#issuecomment-3941718
> > >
> >
>
> _______________________________________________
> cffi-devel mailing list
> cffi-devel at common-lisp.net
> http://lists.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20120220/81a6ae4b/attachment.html>


More information about the cffi-devel mailing list