Jack Unrue | 5 Jun 2006 00:51
Picon

corrupted foreign structure testcase with latest CFFI and LW 4.4.6

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
(Continue reading)

Jack Unrue | 5 Jun 2006 00:57
Picon

Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6

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.

--

-- 
Jack Unrue
Jack Unrue | 5 Jun 2006 01:00
Picon

Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6

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)))

--

-- 
Jack Unrue
Luke Crook | 7 Jun 2006 00:40
Gravatar

Passing a struct by value


I've read: http://article.gmane.org/gmane.lisp.cffi.devel/754 stating that CFFI 
does not support passing structs by value. Unfortunately I need to pass a 
SDL_Color struct *by value* to the SDL_ttf library in order to set the 
character/font color prior to rendering.

I'll need to write some 'glue' code in C to do this conversion. Does anyone have 
any suggestions on the best way I should implement this? A 'wrapper' function in 
a helper DLL that will take the SDL_Color struct pointer from CFFI and call the 
SDL_ttf function passing the struct as a value?

Thanks,
-Luke
Luke Crook | 7 Jun 2006 00:53
Gravatar

Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6

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
Luís Oliveira | 7 Jun 2006 04:37
Picon
Gravatar

Re: Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6

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. :-)

--

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Luis Oliveira | 7 Jun 2006 06:00
Gravatar

New patches: 6-Jun-2006


Tue Jun  6 22:23:58 EDT 2006  Luis Oliveira <loliveira <at> common-lisp.net>
  * Huh. Found a very old and incomplete sentence in the manual.

    M ./doc/cffi-manual.texinfo -1 +1

Tue Jun  6 22:23:35 EDT 2006  Luis Oliveira <loliveira <at> common-lisp.net>
  * Minor comestic change in foreign-vars.lisp

    M ./src/foreign-vars.lisp -3 +2

Tue Jun  6 22:23:25 EDT 2006  Luis Oliveira <loliveira <at> common-lisp.net>
  * Lispworks bugfix: %mem-ref and %mem-set compiler macros

  - The %mem-ref and %mem-set in cffi-lispworks.lisp were using
    bogus indexes. FLI's documentation suggests foreign-typed-aref
    expects array indexes but it seems to want offsets in bytes
    instead.
  - Regression tests: mem-ref.rt.1 and mem-ref.rt.2.

    M ./src/cffi-lispworks.lisp -26 +8
    M ./tests/memory.lisp +24

An updated tarball of CFFI's source can be downloaded here:
http://common-lisp.net/project/cffi/tarballs/cffi-060606.tar.gz

Darcsweb URL:
http://common-lisp.net/cgi-bin/darcsweb/darcsweb.cgi?r=cffi;a=summary
Luís Oliveira | 7 Jun 2006 16:57
Picon
Gravatar

Re: Passing a struct by value

Luke Crook <luke <at> balooga.com> writes:
> I've read: http://article.gmane.org/gmane.lisp.cffi.devel/754 stating
> that CFFI does not support passing structs by value. Unfortunately I
> need to pass a SDL_Color struct *by value* to the SDL_ttf library in
> order to set the character/font color prior to rendering.

Right, that's because most lisps don't support this. But we could in
theory add this to CFFI for lisps that support it. (I think OpenMCL
supports this.)

> I'll need to write some 'glue' code in C to do this conversion. Does
> anyone have any suggestions on the best way I should implement this? A
> 'wrapper' function in a helper DLL that will take the SDL_Color struct
> pointer from CFFI and call the SDL_ttf function passing the struct as
> a value?

Either that or a C function which accepts an argument for each of
SDL_Color's struct members.

--

-- 
Luís Oliveira
luismbo ( <at> ) gmail (.) com
http://student.dei.uc.pt/~lmoliv/
Luís Oliveira | 7 Jun 2006 20:53
Picon
Gravatar

Running the test-suite with the tests compiled. (was: Re: Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6)


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.

--

-- 
Luís Oliveira
http://student.dei.uc.pt/~lmoliv/
Jack Unrue | 7 Jun 2006 23:41
Picon

Re: Running the test-suite with the tests compiled. (was: Re: Re: corrupted foreign structure testcase with latest CFFI and LW 4.4.6)

On 6/7/06, Luís Oliveira <luismbo <at> 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

Gmane