[plt-scheme] Re: Using FFI with complex structures and input/output parameters?
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>