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