[plt-scheme] Using FFI with complex structures and input/output parameters?

From: Eli Barzilay (eli at barzilay.org)
Date: Tue Jun 30 12:20:50 EDT 2009

On Jun 30, Elena Garrulo wrote:
> Hello,
> 
> I'm trying to wrap a Windows DLL using FFI.
> 
> I got past the simpler functions, but I'm getting lost when it comes
> to input/output of complex structures.
> 
> I'm attaching a stripped down version of my code, which ends calling
> the "SCardTransmit" function and fails with "zero?: expects argument
> of type <real number>; given #<cpointer>".

>From a brief look at the code, it looks like

    IN OUT LPSCARD_IO_REQUEST pioRecvPci, // It can be NULL.

means that it is a pointer, but you're using

    (ioRecvPci : (_ptr io _SCARD_IO_REQUEST-pointer/null))

which is sending out a pointer to the pointer instead.  The `io' modes
for _ptr etc is not frequently useful -- it allocates a pointer to a
value before the foreign call, then does the call, and then
dereferences the value.  It is more likely that you need to just use
`_SCARD_IO_REQUEST-pointer/null'.

I also noticed that you do

    (define _DWORD _int)
    (define _LONG _int)

I don't remember exactly the windows convention, but the first might
be better defined with `_int16', and the second with `_long'.


> I'd also like to know whether there is a way to automatically
> evaluate C structures' size (currently I'm doing it manually).

This:

  (ctype-sizeof _SCARD_IO_REQUEST)

works fine.

-- 
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!


Posted on the users mailing list.