Hello:

I have a problem with cffi and I don't know if I'm doing something wrong or if It's a bug.

I'm writting a ffi interface to a windowing kit. When testing It I became in problems. The windowing kit has a struct called Rect with the following definition:

struct Rect

{

    int x;

    int y;

    int width;

    int height;

};

plus a functional interface to create Rect objects:

Rect app_new_rect(int x , int y , int w , int h ) ;

That function works well because I can run the examples of the toolkit and I see the windows. But when I create the cffi interface, I have problems.

The cffi interface for app_new_rect is:

(cffi:defcstruct Rect

    (x :int)

    (y :int)

    (width :int)

    (height :int))

 

(cffi:defcfun ("app_new_rect" app_new_rect) Rect

    (x :int)

    (y :int)

    (width :int)

    (height :int))

The problem is that when I use the Rect object that this function creates, I get segmentation faults. Ex:

CL-USER> (setq r (app_new_rect 0 0 200 300 ) )

#.(SB-SYS:INT-SAP #X00000000)

CL-USER> (with-foreign-slots ( (x y width height ) r Rect )

                             (list x y width height )

                 )

Unhandled memory fault at #x0.

[Condition of type SB-SYS:MEMORY-FAULT-ERROR]

Restarts:

0: [ABORT] Return to SLIME's top level.

1: [TERMINATE-THREAD] Terminate this thread (#<THREAD "repl-thread" {1002886941}>)

Backtrace:

0: (SB-SYS:MEMORY-FAULT-ERROR)

1: (SB-SYS:MEMORY-FAULT-ERROR)

2: ("foreign function: call_into_lisp")

3: ("foreign function: post_signal_tramp")

4: (NIL)

5: (SB-INT:SIMPLE-EVAL-IN-LEXENV

(WITH-FOREIGN-SLOTS ((X Y WIDTH HEIGHT) R RECT)

(LIST X Y WIDTH HEIGHT))

#<NULL-LEXENV>)

 

When I had that problem, I tried to write a Lisp-only function to create Rect objects , to not use app_new_rect at all. I wrote the next function:

(defun rect ( x y width height )

               (cffi:with-foreign-object ( ptr 'rect )

               (setf (cffi:foreign-slot-value ptr 'rect 'x ) x )

               (setf (cffi:foreign-slot-value ptr 'rect 'y ) y )

               (setf (cffi:foreign-slot-value ptr 'rect 'width ) width )

               (setf (cffi:foreign-slot-value ptr 'rect 'height ) height )

               ptr

         )

)

But my surprise is that this doesn't set correctly the values of the slots. See the following output from slime:

 

CL-USER> (setq my-little-rectangle (rect 0 0 200 300 ) )

; in: LAMBDA NIL

; (SETQ MY-LITTLE-RECTANGLE (RECT 0 0 200 300))

;

; caught WARNING:

; undefined variable: MY-LITTLE-RECTANGLE

;

; caught WARNING:

; This variable is undefined:

; MY-LITTLE-RECTANGLE

;

; compilation unit finished

; caught 2 WARNING conditions

#.(SB-SYS:INT-SAP #X2ACC75E76FE8)

CL-USER> (with-foreign-slots ( (x y width height ) my-little-rectangle Rect )

(list x y width height )

)

; in: LAMBDA NIL

; (LET ((#:PTR2816 MY-LITTLE-RECTANGLE))

; (SYMBOL-MACROLET ((X (FOREIGN-SLOT-VALUE #:PTR2816 'RECT 'X))

; (Y (FOREIGN-SLOT-VALUE #:PTR2816 'RECT 'Y))

; (WIDTH (FOREIGN-SLOT-VALUE #:PTR2816 'RECT 'WIDTH))

; (HEIGHT (FOREIGN-SLOT-VALUE #:PTR2816 'RECT 'HEIGHT)))

; (LIST X Y WIDTH HEIGHT)))

;

; caught WARNING:

; undefined variable: MY-LITTLE-RECTANGLE

;

; caught WARNING:

; This variable is undefined:

; MY-LITTLE-RECTANGLE

;

; compilation unit finished

; caught 2 WARNING conditions

(1192261452 0 785098 0)

 

The output from the last input should be (0 0 200 300) but I get (1192261452 0 785098 0 ). As the Rect object is used for drawing, nothing works for me.

Please, can anyone explain me what I'm doing wrong? I use an AMD64 on OpenSuse 10.1 x86_64, plus sbcl-1.0.9-x86_64 and cffi_0.9.2 . I've tested also the snapshot cffi-070901 and I get the same problem.

Thank you.



--
Felip Alàez Nadal