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

From: Elena Garrulo (egarrulo at gmail.com)
Date: Tue Jun 30 08:44:58 EDT 2009

Sorry, but my mail client messed up my code. I'm attaching it as text.


2009/6/30, Elena Garrulo <egarrulo at gmail.com>:
> 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>".
>
> I'd also like to know whether there is a way to automatically evaluate
> C structures' size (currently I'm doing it manually).
>
> Software:
> - PLT Scheme 4.2;
> - Windows XP SP3
>
> Thank you very much.
>
>
>
> ;; CODE FOLLOWS
>
> (require mzlib/foreign)
> (unsafe!)
>
>
>   (define winscard (ffi-lib "winscard"))
>
>   (define _DWORD _int)
>   (define _LONG _int)
>   (define _SCARDHANDLE _int) ;; AN OPAQUE POINTER WOULD BE BETTER.
>
>   (define 	+SCARD_PROTOCOL_T0+   #x0001) ;; T=0 active protocol.
>   (define 	+SCARD_PROTOCOL_T1+   #x0002) ;; T=1 active protocol.
>   (define 	+SCARD_PROTOCOL_ANY+   (bitwise-ior +SCARD_PROTOCOL_T0+
> +SCARD_PROTOCOL_T1+))
>
>
>   (define-cstruct _SCARD_IO_REQUEST ((dwProtocol _DWORD)
>                                      (cbPciLength _DWORD)))
>
>   (define +sizeof-SCARD_IO_REQUEST+ (+ (ctype-sizeof _DWORD)
>                                        (ctype-sizeof _DWORD))) ;; Any
> way to have it generated automatically?
>
>
> #|
> LONG SCardTransmit(
>     IN     SCARDHANDLE hCard,
>     IN     LPCSCARD_IO_REQUEST pioSendPci,
>     IN     LPCBYTE pbSendBuffer,
>     IN     DWORD cbSendLength,
>     IN OUT LPSCARD_IO_REQUEST pioRecvPci, // It can be NULL.
>     OUT    LPBYTE pbRecvBuffer,
>     IN OUT LPDWORD pcbRecvLength);
> |#
>   (define SCardTransmit
>     (get-ffi-obj "SCardTransmit"
>                  winscard
>                  (_fun (hCard : _SCARDHANDLE) ;; == IN SCARDHANDLE hCard
>                        (pioSendPci : (_ptr i _SCARD_IO_REQUEST)) ;; ==
> IN LPCSCARD_IO_REQUEST pioSendPci
>                        (pbSendBuffer : (_vector i _byte)) ;; == IN
> LPCBYTE pbSendBuffer
>                        (_DWORD = (vector-length pbSendBuffer)) ;; ==
> IN DWORD cbSendLength
>                        (ioRecvPci : (_ptr io
> _SCARD_IO_REQUEST-pointer/null)) ;; == IN OUT LPSCARD_IO_REQUEST
> pioRecvPci
>                        (pbRecvBuffer :  (_vector o _byte
> cbRecvLength)) ;; == OUT LPBYTE pbRecvBuffer
>                        (cbRecvLength : (_ptr io _DWORD)) ;; == IN OUT
> LPDWORD pcbRecvLength
>                        -> (error : _LONG)
>                        )))
>
>
>
>
> (SCardTransmit 1
>                 (make-SCARD_IO_REQUEST +SCARD_PROTOCOL_ANY+
> +sizeof-SCARD_IO_REQUEST+)
>                 (make-vector 4 0)
>                 ;; cbSendLength AUTOMATICALLY GENERATED.
>                 #f ;; PASSING NULL.
>                 ;; pbRecvBuffer SKIPPED SENCE IS AN OUTPUT PARAMETER.
>                 4
>                 )
>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: main.ss
Type: application/octet-stream
Size: 2240 bytes
Desc: not available
URL: <http://lists.racket-lang.org/users/archive/attachments/20090630/a77ef6ac/attachment.obj>

Posted on the users mailing list.