[plt-scheme] Win32 FFI: Handling structures.

From: Elena Garrulo (egarrulo at gmail.com)
Date: Fri Oct 3 08:28:44 EDT 2008

Hi,

I'm wrapping Win32 PC/SC and I don't understand how I should wrap
structures. Here is my simplified header:

============= C HEADER =============

#define IN /* Tag for INPUT parameters */
#define OUT /* Tag for OUTPUT parameters */


typedef int DWORD;
typedef int LONG;

typedef LONG SCARDHANDLE;

typedef unsigned char BYTE;
typedef const BYTE* LPCBYTE;
typedef DWORD* LPDWORD;

typedef struct _SCARD_IO_REQUEST{
    DWORD dwProtocol;   // Protocol identifier
    DWORD cbPciLength;  // Protocol Control Information Length
} SCARD_IO_REQUEST, *PSCARD_IO_REQUEST, *LPSCARD_IO_REQUEST;
typedef const SCARD_IO_REQUEST *LPCSCARD_IO_REQUEST;


LONG SCardTransmit(
    IN SCARDHANDLE hCard,
    IN LPCSCARD_IO_REQUEST pioSendPci,
    IN LPCBYTE pbSendBuffer,
    IN DWORD cbSendLength,
    IN OUT LPSCARD_IO_REQUEST pioRecvPci,
    OUT LPBYTE pbRecvBuffer,
    IN OUT LPDWORD pcbRecvLength);


============= END OF C HEADER =============


Here is my conversion attempt:



============= SCHEME MODULE  =============

;; #lang mzscheme
(module winscard mzscheme
  (require mzlib/foreign)
  (unsafe!)

  (define winscard (ffi-lib "winscard"))

  (define _DWORD _int)
  (define _LONG _int)
  (define _SCARDHANDLE _int)

  (provide scard-ok)
  (define (scard-ok scard-error)
    (= scard-error 0))
  (provide make-SCARD_IO_REQUEST)
  (define-cstruct _SCARD_IO_REQUEST ([dwProtocol _DWORD];;   // Protocol
identifier
                                     [cbPciLength _DWORD])) ;;  // Protocol
Control Information Length

  #|
LONG SCardTransmit(
    IN SCARDHANDLE hCard,
    IN LPCSCARD_IO_REQUEST pioSendPci,
    IN LPCBYTE pbSendBuffer,
    IN DWORD cbSendLength,
    IN OUT LPSCARD_IO_REQUEST pioRecvPci,
    OUT LPBYTE pbRecvBuffer,
    IN OUT LPDWORD pcbRecvLength);
|#
  (provide scard-transmit)
  (define scard-transmit
    (get-ffi-obj "SCardTransmit"
                 winscard
                 (_fun (hCard : _SCARDHANDLE) ;; == IN SCARDHANDLE hCard
                       (pioSendPci : _SCARD_IO_REQUEST-pointer) ;; == IN
LPCSCARD_IO_REQUEST pioSendPci
                       (pbSendBuffer : (_vector i _byte)) ;; == IN LPCBYTE
pbSendBuffer
                       (cbSendLength : _DWORD) ;; == IN DWORD cbSendLength
                       (ioRecvPci : (_ptr io _SCARD_IO_REQUEST)) ;; == IN
OUT LPSCARD_IO_REQUEST pioRecvPci
                       (pbRecvBuffer :  (_vector o _byte cbRecvLength)) ;;
== OUT LPBYTE pbRecvBuffer
                       (cbRecvLength : (_ptr io _DWORD)) ;; == IN OUT
LPDWORD pcbRecvLength
                       -> (error : _LONG)
                       -> (if (scard-ok error) '(error ioRecvPci
pbRecvBuffer cbRecvLength) #f)
                       )))
    )

============= END OF SCHEME MODULE  =============


============= SCHEME PROGRAM  =============
(require "winscard.ss")
(require mzlib/foreign)
(unsafe!)

(define hCard 1)
(define pioSendPci (make-SCARD_IO_REQUEST #x0002 8))
(define pbSendBuffer (make-vector 4 0))
(define cbSendLength 4)
(define ioRecvPci (make-SCARD_IO_REQUEST #x0002 8))
(define cbRecvLength 4)
(scard-transmit
 hCard
 pioSendPci
 pbSendBuffer
 cbSendLength
 ioRecvPci
 ;; pbRecvBuffer skipped since it's an output parameter
 cbRecvLength)

============= END OF SCHEME PROGRAM  =============

Program fails with: "zero?: expects argument of type <real number>; given
#<cpointer>".

Any hint? Thanks.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20081003/de195146/attachment.html>

Posted on the users mailing list.