Re: Strange behavior with the FLI
Hello,
Some new finding about this issue:
- the same code with LispWorks Professional 32 bits on Mac OS X works as expected.
- I am almost sure that each call to the foreign functions [see 1] overwrite the stack next where the other dynamic foreign objects buffers are allocated. This is why a different order of the foreign function calls gives different results.
- I have tried with GCC instead of clang without success.
- I have not tried to return the structure by passing a pointer to the foreign functions (instead of returning the struct by value as it is right now), but I have good faith that it would work, yet I would really love to understand why my foreign allocations are overwritten.
Best,
Cam
[1]
(fli:with-dynamic-foreign-objects ((direction vector)
(position vector)
(velocity vector))
;; each call here overwrite the stack by 4 more bytes
(direction :result-pointer direction)
(position :result-pointer position)
(velocity :result-pointer velocity)
(list :direction (dump-vector direction))
:position (dump-vector position))
:velocity (dump-vector velocity))))
On 23 janv. 2013, at 01:05, Camille Troillard <camille@osculator.net> wrote:
> Hello,
>
> I am interfacing LispWorks 64 bits on Mac OS X to C functions returning a very simple structure:
>
> struct _vector {
> float x;
> float y;
> float z;
> }
> typedef struct _vector vector;
>
> vector direction();
> vector position();
> vector velocity();
>
>
> In LispWorks, when I call this:
>
> (fli:with-dynamic-foreign-objects ((direction vector)
> (position vector)
> (velocity vector))
> (direction :result-pointer direction)
> (position :result-pointer position)
> (velocity :result-pointer velocity)
> (list :direction (dump-vector direction))
> :position (dump-vector position))
> :velocity (dump-vector velocity))))
>
> Where:
>
> (defun dump-vector (vector)
> (list (fli:foreign-slot-values vector 'x)
> (fli:foreign-slot-values vector 'y)
> (fli:foreign-slot-values vector 'z)))
>
> The result I get is something like:
>
> (DIRECTION (0.0 yyy1 zzz1)
> POSITION (0.0 yyy2 zzz2)
> VELOCITY (xxx3 yyy3 zzz3))
>
> The value 0.0 for the component X of direction and position is unexpected, I know the C library does not return 0.0. More surprising, velocity has all its 3 components with non 0.0 values.
>
>
> Now, if I change the order to something else:
>
> (fli:with-dynamic-foreign-objects ((direction vector)
> (position vector)
> (velocity vector))
> ;;
> ;; I have swapped the first two lines below...
> ;;
> (position :result-pointer position)
> (direction :result-pointer direction)
> (velocity :result-pointer velocity)
> (list :direction (dump-vector direction))
> :position (dump-vector position))
> :velocity (dump-vector velocity))))
>
>
> I get a slightly better result, a component is still 0.0 though ...
>
> (DIRECTION (xxx1 yyy1 zzz1)
> POSITION (0.0 yyy2 zzz2)
> VELOCITY (xxx3 yyy3 zzz3))
>
>
> Now I have found that this outputs the correct results:
>
> (fli:with-dynamic-foreign-objects ((direction vector)
> (position vector)
> (velocity vector))
> ;;
> ;; the three following lines were swapped...
> ;;
> (velocity :result-pointer velocity)
> (position :result-pointer position)
> (direction :result-pointer direction)
> (list :direction (dump-vector direction))
> :position (dump-vector position))
> :velocity (dump-vector velocity))))
>
>
> I'm unsure of this but it looks like my foreign objects which size is 12 bytes are aligned on a 16 bytes boundary, but somehow accessed contiguously. Can an enlightening soul please help me understand why?
>
>
> All the best,
> Cam
>
>
>
> _______________________________________________
> Lisp Hug - the mailing list for LispWorks users
> lisp-hug@lispworks.com
> http://www.lispworks.com/support/lisp-hug.html
>
_______________________________________________
Lisp Hug - the mailing list for LispWorks users
lisp-hug@lispworks.com
http://www.lispworks.com/support/lisp-hug.html