I've run into a problem where populating a foreign structure and then passing it to a foreign function behaves correctly if my Lisp code is interpreted, but the structure fields appear to be corrupted if my function is compiled. This is with CFFI versions later than 0.9.0, and on LW 4.4.6 under WinXP.
When I invoke the dump-it function in interpreted mode, the output file contains the expected result:
cbSize: 4 style: 01abcdef
When I (compile 'dump-it) and then invoke it, the output file contains garbage:
cbSize: -1412567292 style: 01abcd01
This testcase works fine with the same LW version but CFFI 0.9.0. It also works fine with CLISP 2.38 and latest CFFI.
CFFI versions 0.9.1, 060514, and a build produced from a darcs pull today all show the problem on LW. I haven't tried bisecting any further.
See attached testcase.lisp and structs.c. I've also attached a simple Makefile for compiling with gcc. The foreign function dump_blah writes a file called 'dump_output.txt' in the current working directory.
I wrote:
CFFI versions 0.9.1, 060514, and a build produced from a darcs pull today all show the problem on LW. I haven't tried bisecting any further.
Whoops, 0.9.1 works OK too. Don't know what I was smoking...
But this is somewhat puzzling, because the larger test case that I boiled this problem down to does have a similar problem on 0.9.1.
OK, the mailing list manager scrubbed my other two attachments. Here is the Lisp code inline:
(cffi:load-foreign-library "structs.dll")
(cffi:defcfun ("dump_blah" dump-blah) :void (ptr :pointer))
(cffi:defcstruct blah (cbsize :unsigned-int) (style :unsigned-int))
(defun dump-it () (cffi:with-foreign-object (ptr 'blah) (cffi:with-foreign-slots ((cbsize style) ptr blah) (setf cbsize 4) (setf style #x01ABCDEF)) (dump-blah ptr)))
I think this foreign struct problem with LW goes all the way back to cffi- 060214. Something changed between cffi-060213 and cffi-060214 for Lispworks for Windows that messes up foreign structs. I'm having to use cffi-060213 in the lispbuilder-sdl project (only for Lispworks in win32) for this very reason. The examples work just fine in CLISP for win32, as well as SBCL for Linux using the latest and greatest CFFI.
-Luke
On 6/6/06, Luke Crook luke@balooga.com wrote:
I think this foreign struct problem with LW goes all the way back to cffi- 060214. Something changed between cffi-060213 and cffi-060214 for Lispworks for Windows that messes up foreign structs. I'm having to use cffi-060213 in the lispbuilder-sdl project (only for Lispworks in win32) for this very reason. The examples work just fine in CLISP for win32, as well as SBCL for Linux using the latest and greatest CFFI.
Hmmm....I've now compared snapshots 060210 through 060215 in progressive stages and identified the folowing differences:
The delta between 060210 and 060213 is:
src/foreign-vars.lisp src/functions.lisp src/package.lisp src/types.lisp [plus test file differences]
The delta from 060213 to 060214 is:
src/cffi-allegro.lisp src/cffi-openmcl.lisp src/cffi-sbcl.lisp [plus test file differences]
And from 060214 to 060215 we have:
src/cffi-lispworks.lisp src/package.lisp src/types.lisp [plus doc and test file differences]
The changes in 060215's version of cffi-lispworks.lisp are that the following have been added:
defun convert-foreign-typed-aref-type defun pointer-and-index compiler macros for %mem-ref and %mem-set
Hopefully this code spelunking can help track down what's happened :-)
On 2006-jun-07, at 00:58, Jack Unrue wrote:
The changes in 060215's version of cffi-lispworks.lisp are that the following have been added:
defun convert-foreign-typed-aref-type defun pointer-and-index compiler macros for %mem-ref and %mem-set
Bingo.
Hopefully this code spelunking can help track down what's happened :-)
Yeah, those compiler macros were calling fli:foreign-typed-aref incorrectly. I remember James and I discussing this optimization and we were both tricked by the documentation that suggests this function takes an array index, not an offset in bytes.
I've pushed a fix to the darcs repository. Thank you for the report and test case. And thank you and Luke for tracking the down the changes that introduced this bug. :-)
On 2006-jun-07, at 03:37, I wrote:
Yeah, those compiler macros were calling fli:foreign-typed-aref incorrectly.
I forgot to mention that this particular issue brought to my attention that, because of the way RT tests are compiled, compiler macros are not kicking in and, therefore, obvious bugs like this are not getting caught by the test suite. (Jörg Höhle has mentioned this before.)
I've changed both the asdf:test-op operation and the run-tests "script" to run the tests both uncompiled and compiled (by binding rt::*compile-tests* to T). I'm not sure how effective this is but it the cffi-lispworks bug discussed in the thread (through many of the structs tests) so it'll hopefully be helpful in finding future bugs in the various compiler macros present in CFFI.
On 6/7/06, Luís Oliveira luismbo@gmail.com wrote:
I've changed both the asdf:test-op operation and the run-tests "script" to run the tests both uncompiled and compiled (by binding rt::*compile-tests* to T). I'm not sure how effective this is but it the cffi-lispworks bug discussed in the thread (through many of the structs tests) so it'll hopefully be helpful in finding future bugs in the various compiler macros present in CFFI.
Thanks Luís.
a happy CFFI user, Jack Unrue