I think Martin is right, so I have implemented mem-aptr and updated the manual. Here are Ryan's examples:
(cffi:defcstruct rp-struct (x :short) (y :short)) (defun test-old-ref (&optional (count 0)) (declare (notinline cffi:mem-ref cffi:mem-aref)) (cffi:with-foreign-object (ptr '(:struct rp-struct) 2) (format t "~&Old-ref style:~%ptr : ~A~%aref: ~A~%" ptr (cffi:mem-aref ptr 'rp-struct count)))) (defun test-new-ref (&optional (count 0)) (cffi:with-foreign-object (ptr '(:struct rp-struct) 2) (format t "~&New-ref style:~%ptr : ~A~%aref: ~A~%" ptr (cffi:mem-aptr ptr '(:struct rp-struct) count)))) CFFI(14): (test-old-ref) STYLE-WARNING: bare references to struct types are deprecated. Please use (:STRUCT RP-STRUCT) instead. STYLE-WARNING: bare references to struct types are deprecated. Please use (:STRUCT RP-STRUCT) instead. STYLE-WARNING: bare references to struct types are deprecated. Please use (:POINTER (:STRUCT RP-STRUCT)) instead. Old-ref style: ptr : #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) aref: #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) NIL CFFI(15): (test-new-ref) New-ref style: ptr : #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) aref: #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) NIL CFFI(16): (test-old-ref 1) STYLE-WARNING: bare references to struct types are deprecated. Please use (:STRUCT RP-STRUCT) instead. STYLE-WARNING: bare references to struct types are deprecated. Please use (:STRUCT RP-STRUCT) instead. STYLE-WARNING: bare references to struct types are deprecated. Please use (:POINTER (:STRUCT RP-STRUCT)) instead. Old-ref style: ptr : #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) aref: #.(SB-SYS:INT-SAP #X7FFFF6E97FF4) NIL CFFI(17): (test-new-ref 1) New-ref style: ptr : #.(SB-SYS:INT-SAP #X7FFFF6E97FF0) aref: #.(SB-SYS:INT-SAP #X7FFFF6E97FF4) NIL This looks right to me. I made a new branch libffi; the old branch fsbv will be abandoned. Note that generation of a pointer from mem-aref for structures is only supported when using the deprecated "bare" structures form, for compatibility reasons; otherwise you should use mem-aptr. Please checkout this branch and see if it works correctly for you and looks right. I agree as Martin said the other examples are incorrectly written, so I'm not bothering with them. Head: 0fec6ff839 - Update manual to include mem-aptr Liam On Fri, Feb 24, 2012 at 7:34 AM, Martin Simmons <mar...@lispworks.com>wrote: > To answer Ryan's point, I think there should be a different function to > get a > pointer to an element of an array, called something like mem-aptr. It > should > work for all element types, not just aggregates. > > That allows mem-aref to have "value" semantics for all types. For > aggregates, > converting to a plist is one possible way to representing it. > > -- > Martin Simmons > LispWorks Ltd > http://www.lispworks.com/ > > > >>>>> On Mon, 20 Feb 2012 12:12:44 -0500, Liam Healy said: > > > > Ryan - > > > > I am forwarding this to CFFI-devel and Martin directly (though I'm pretty > > sure he's subscribed to cffi-devel). Can you please send future messages > > to cffi-devel? I'm not sure many people read the github mailing list; > this > > issue should get wider visibility. Thanks. > > > > Liam > > > > On Mon, Feb 20, 2012 at 12:02 PM, Ryan Pavlik < > > > reply+i-1614209-ba246666762196459413560690eb7d3a39c7c7ee-838...@reply.github.com > > > wrote: > > > > > I'm not sure what you mean. It doesn't really matter that a pointer is > > > aggregate or not. The goal is to get at the Nth member of an > > > array-of-something. In the case of scalar C types, you're getting the > > > value; in the case of structs it's far more useful to get a pointer, > > > because you probably only want a single value out of the struct, or to > > > **put a value into the struct**. (The `setf` form works for scalars > in the > > > latter case, but not for "member-of-struct-of-index-N"... you most > likely > > > want the pointer in these cases.) > > > > > > It also occurred to me after posting that there is no difference > between > > > `(mem-aref ptr '(:pointer (:struct foo)) N)` and just simply > `(mem-aref ptr > > > :pointer N)` ... both return a pointer value as if `ptr` is a `void > > > *ptr[k]`. > > > > > > A struct of more bytes works the same way: > > > > > > ``` > > > (cffi:defcstruct my-struct > > > (x :long) > > > (y :long) > > > (x :long) > > > (t :long)) > > > > > > ... > > > > > > Old-ref style: > > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFC7FB8) > > > aref: #.(SB-SYS:INT-SAP #X7FFFEEFC7FD8) > > > New-ref style: > > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFC7FB8) > > > aref: (T 0 Y 0 X 0) > > > New-ref with :pointer style: > > > ptr : #.(SB-SYS:INT-SAP #X7FFFEEFC7FB8) > > > aref: #.(SB-SYS:INT-SAP #X00000000) > > > ``` > > > > > > Note that on my system, a pointer is 8 bytes, not 4. This is why I > > > initially found the problem, when trying to access an array of points > > > defined by 2 short; each member is 4 bytes, and it was giving offsets > to > > > `sizeof(void*)`. > > > > > > --- > > > Reply to this email directly or view it on GitHub: > > > https://github.com/cffi/cffi/pull/2#issuecomment-4057418 > > > > > >
_______________________________________________ cffi-devel mailing list cffi-devel@common-lisp.net http://lists.common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel