Liam Healy | 18 Feb 2012 18:53

Re: [cffi] FSBV (#2)

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 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
Martin Simmons | 20 Feb 2012 16:38
Favicon

Re: [cffi] FSBV (#2)

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
> >
> 
Liam Healy | 20 Feb 2012 17:40

Re: [cffi] FSBV (#2)

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

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

Gmane