<div dir="ltr">Willem,<div><br></div><div>Thanks for the report.</div><div><br></div><div>My thinking is that with-foreign-slots is intended to expose the value (and not the pointer), and therefore, expands to foreign-slot-value, so the behavior you're seeing is correct. Your fix to your code is the correct way to access the pointer. I think with-foreign-slots is provided as a convenient shortcut to get all the values; since it doesn't do what you need, you need to use the actual access form (foreign-slot-pointer in your case).</div>


<div><br></div><div>For your second question: if the argument is actually a pointer to the structure, :pointer is the right thing to use. Are you sure it is a pointer argument? Check the .h file where it is defined.</div>


<div><br></div><div>Liam</div></div><div class="gmail_extra"><br><br><div class="gmail_quote">On Sat, Apr 20, 2013 at 4:40 AM, Willem Rein Oudshoorn <span dir="ltr"><<a href="mailto:woudshoo@xs4all.nl" target="_blank">woudshoo@xs4all.nl</a>></span> wrote:<br>


<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">I am encountering some problems with trying to upgrade my old cffi code<br>
to the new version from quicklisp.<br>
If I use the old code, I get lots of warnings about my structs, that I<br>
should use either (:struct ...) or (:pointer (:struct ...))<br>
<br>
However whateer I try, I do not seem to get it to work, and I am<br>
starting to think there is some issue between me and the new cffi.<br>
<br>
<br>
The main issue is a nested struct definition like this:<br>
<br>
```<br>
(defcstruct timeval<br>
  (time %time)<br>
  (offset :int))<br>
<br>
(defcstruct (git-signature)<br>
  (name :string)<br>
  (email :string)<br>
  (time (:struct timeval)))<br>
```<br>
<br>
With type definitions<br>
<br>
```<br>
(define-foreign-type time-type ()<br>
  nil<br>
  (:actual-type :int64)<br>
  (:simple-parser %time))<br>
<br>
(define-foreign-type git-signature-type ()<br>
  nil<br>
  (:actual-type :pointer)<br>
  (:simple-parser %git-signature))<br>
```<br>
<br>
I encounter problems when I am trying to update the<br>
`translate-to-foreign` for the `git-signature-type`.<br>
The implementation boils down to:<br>
<br>
```<br>
(defmethod translate-to-foreign ((value list) (type git-signature-type))<br>
  (let ((signature (foreign-alloc '(:struct git-signature))))<br>
    (with-foreign-slots ((name email time) signature (:struct git-signature))<br>
      (setf name (getf value :name (getenv "USER")))<br>
      (setf email (getf value :email (default-email)))<br>
      (with-foreign-slots ((time offset) time (:struct timeval))<br>
        (let ((time-to-set (getf value :time (local-time:now))))<br>
          (setf time time-to-set)<br>
          (setf offset (/ (local-time:timestamp-subtimezone<br>
                           time-to-set local-time:*default-timezone*)<br>
                          60)))))<br>
    signature)<br>
```<br>
<br>
The problem is in the inner `with-foreign-slots ((time offset)...`.<br>
<br>
The error I get is:<br>
<br>
; Evaluation aborted on #<TYPE-ERROR expected-type: SYSTEM-AREA-POINTER<br>
             datum: (CL-GIT::OFFSET 0 TIME @1970-01-01T01:00:03.000000+01:00)>.<br>
<br>
<br>
The reason is, as far as I can tell, that in the code:<br>
<br>
    (with-foreign-slots ((time offset) time (:struct timeval)) ...<br>
<br>
the value of `time` is already a plist (due to the outer<br>
with-foreign-slots), and the inner with-foreign-slots expects a pointer.<br>
<br>
So what is the best way of fixing this?  I can fix this by replacing<br>
the inner `with-foreign-slots` by<br>
<br>
```<br>
      (with-foreign-slots ((time offset)<br>
                           (foreign-slot-pointer signature '(:struct git-signature) 'time)<br>
                           (:struct timeval))<br>
```<br>
which seems a bit long.<br>
<br>
<br>
An additional question is, when to use (:struct ...) and when to use<br>
(:pointer (:struct ..)))<br>
<br>
I did expect that I needed to use (:pointer (:struct ..))<br>
in the toplevel `with-foreign-slots`, because the argument is actually<br>
a pointer to the struct.  But that did not work.<br>
<br>
<br>
As you can tell, I am a bit confused.<br>
Hope that someone can give some hints to clear my head.<br>
<br>
Kind regards,<br>
Wim Oudshoorn.<br>
<br>
<br>
</blockquote></div><br></div>