Hi,
There is and example of getting struct parameters in the current GUI-Toy
version in "sdl-interface.scm".
=============IN PROCESS FYI================
[YOU CAN SKIP THIS]
FYI, one of the things I am looking at is the difference between direct FFI
calls and using a pipe to a sub-process. The "pipe" interface allows for
rapid porting (currently GUI-Toy runs on Gambit, Larceny, PLT, Ypsilon, Chez,
and Ikarus Schemes).
To make adding calls easy, I have started a declarative "FFI" which writes
both the Scheme and C code.
(describe-interface
; ...
(describe-call
(Scheme SDL::load-bmp-file
(file-name-string char*))
(C "SDL_LoadBMP"
(file-name-string)
(pointer "SDL_Surface")))
(describe-c-struct SDL_Rect
(x Sint16) (y Sint16)
(w Uint16) (h Uint16))
(describe-access (SDL_Rect rectangle?)
; (c-field-name scheme-getter-name) ...
(x x) (y y) (w width) (h height))
(describe-call
(Scheme SDL::draw-rect
(surface (pointer "SDL_Surface"))
(rect (access rectangle? SDL_Rect))
(rgb-color Uint32))
(C "SDL_FillRect"
(surface rect rgb-color) void))
;...
)
The generated Scheme code does basic error checks and reporting, puts out a
shared call tag/id, and accesses object fields to "spread" the values for
the "call".
(define (SDL::draw-rect surface rect rgb-color)
(unless (Uint32? surface)
(report-arg-check-error
'SDL::draw-rect 'surface 'Uint32?))
(unless (rectangle? rect)
(report-arg-check-error
'SDL::draw-rect 'rect 'rectangle?))
(unless (Uint32? rgb-color)
(report-arg-check-error
'SDL::draw-rect 'rgb-color 'Uint32?))
(put-Uint8 port->sdl 34) ; call tag
(put-Uint32 port->sdl surface)
(put-Sint16 port->sdl [$ x rect])
(put-Sint16 port->sdl [$ y rect])
(put-Uint16 port->sdl [$ width rect])
(put-Uint16 port->sdl [$ height rect])
(put-Uint32 port->sdl rgb-color)
(flush-output-port port->sdl)
)
The generated C code dispatches on the call tag, stack allocates temporaries,
makes the SDL call, and returns a result as required.
case (char)(34):
{ /* SDL::draw-rect -> SDL_FillRect */
unsigned char buf[16];
read(fileno(stdin), buf, 16);
int offset = 0 ;
/* surface */
Uint32 surface
= getUint32( buf, offset ) ;
offset += sizeof( Uint32 ) ;
/* rect */
SDL_Rect rect ;
rect.x = getSint16(buf, offset) ;
offset += sizeof( Sint16 ) ;
rect.y = getSint16(buf, offset) ;
offset += sizeof( Sint16 ) ;
rect.w = getUint16(buf, offset) ;
offset += sizeof( Uint16 ) ;
rect.h = getUint16(buf, offset) ;
offset += sizeof( Uint16 ) ;
/* rgb-color */
Uint32 rgb_color
= getUint32( buf, offset ) ;
offset += sizeof( Uint32 ) ;
SDL_FillRect( (SDL_Surface*)(surface),
&(rect),
rgb_color );
}
break;
I hope at some point to gen both "Scheme native" FFI and the "pipe call"
interface. NYI.
This is all stuff in progress, not ready for prime time, but may give you some
ideas. I plan to report on things at the upcoming Scheme Workshop in
Victoria, BC. If you happen to get there, perhaps we can chat.
Cheers,
-KenD