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