[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Foreign Function Interface

> We are trying to use the Foreign Function Interface (FFI), together with MPW
> PASCAL, to simulate the [Not In ROM] system tools (e.g., the RAM Serial
> Driver).  
> This is the problem:
> (1) The Inside MAC PASCAL calls require VAR argument calls to types other
> than FLOAT or PSTRING.  For example, 
> SerGetBuf (refNum: INTEGER; VAR count: LONGINT) : OSErr
> requires a VAR LONGINT type argument.  However, MACL doesn't support these
> types with the :by-reference flag.  
> (2) In fact, many types, such as RECORDs, ARRAYs, and the hundreds of
> MACINTOSH defined PASCAL types, do not appear to be supported by the FFI
> mechanism.  
> Our questions are: 
> (1) Short of rewriting every [Not In ROM] call to conform to the few supported
> FFI types, how can we more easily achieve this functionality?
> (2) In general, how can we use the FFI with both standard and user-defined
> types?  

I think that both of your problems can be solved with the rlet or %stack-block
macros. VAR arguments, RECORDS and ARRAYS (which are longer than 4 bytes)
are passed as pointers to a location in memory. For VAR arguments, you need
to allocate some temporary space & pass a pointer to it. That's exactly
the function of rlet and %stack-block. Rlet lets you specify either a record
type or a "Pascal type"e.g. :longint. %stack-block and %vstack-block
simply takes a size in bytes.

(rlet ((pointer :longint))
  (SetSerbuf refnum pointer)
  (%get-long pointer))

should do the trick as long as you declard the second argument to SetSerBuf
as type :ptr. You can do the same with any RECORD and ARRAY. 

One note of interest for you... There's a file called serial-streams.lisp
which is a complete interface to the serial drivers on cambridge.apple.com
via anonymous ftp! (/pub/MACL/CONTRIB). It's a re-write of the old
serial-streams code from 1.1 days that I did when I was an apple employee
this past summer...

Joe Chung