Calling C functions from Scheme
===============================

The external-calls structure exports several ways to call C functions from Scheme, along with several other related utilities, many of which are also available from other structures.  There are two different ways to call C functions from Scheme, depending on how the C function was obtained:

 -- Scheme procedure: call-imported-binding binding argument ... returns value
 -- Scheme procedure: call-external-value byte-vector name argument ... returns value
     Each of these applies its first argument, a C function, to the rest of the arguments.  For call-imported-binding, the function argument must be an imported binding.  For call-external-value, the function argument must be a byte vector that contains a pointer to a C function, and NAME should be a string that names the function. The NAME argument is used only for printing error messages.

     For both of these, the C function is passed the argument values, and the value returned is that returned by the C function.  No automatic representation conversion occurs for either arguments or return values.  Up to twelve arguments may be passed.  There is no method supplied for returning multiple values to Scheme from C or vice versa (mainly because C does not have multiple return values).

     Keyboard interrupts that occur during a call to a C function are ignored until the function returns to Scheme. (This is clearly a problem; we are working on a solution.)

 -- Scheme syntax: import-definition name [c-string]
 -- Scheme syntax: import-lambda-definition name formals [c-string]
     These macros simplify importing bindings from C into Scheme and wrapping such bindings in Scheme procedures.  Import-definition defines NAME to be the shared binding named by C-STRING, whose value, if it is not supplied, is by default a string of NAME, downcased and with all hyphens translated to underscores.

          (define NAME (lookup-imported-binding C-STRING)) lisp

          For example,

               (import-definition my-foo)
                   ==> (define my-foo (lookup-imported-binding "my_foo")) lisp

               Import-lambda-definition imports the named C binding, using
               either the provided C binding name or by translating the Scheme name
               as with import-definition, and defines NAME to be a
               procedure with the given formal parameter list that calls the imported
               C binding with its arguments:

                    (define BINDING (lookup-imported-binding C-STRING))
                    (define (NAME FORMAL ...)
                      (call-imported-binding BINDING FORMAL ...)) lisp

                    Examples:

                         (import-lambda-definition integer->process-id (int)
                                                   "posix_getpid")
                             ==>
                         (define BINDING0
                                 (lookup-imported-binding "posix_getpid"))
                         (define (integer->process-id int)
                           (call-imported-binding BINDING0 int))

                         (import-lambda-definition s48-system (string))
                             ==>
                         (define BINDING1
                                 (lookup-imported-binding "s48_system"))
                         (define (s48-system string)
                           (call-imported-binding BINDING1 string)) lisp

                         where BINDING0 and BINDING1 are fresh, unused
                         variable names.

                         Warning: Import-lambda-definition, as presently
                         implemented, requires a fixed parameter list; it does not allow `rest
                         list' arguments.

 -- Scheme procedure: lookup-imported-binding name returns shared-binding
 -- Scheme procedure: define-exported-binding shared-binding returns unspecified
 -- Scheme procedure: shared-binding-ref shared-binding returns value
     These are identical to the procedures accessible with the same names from the Shared bindings between Scheme and C, shared-bindings structure.

 -- Scheme procedure: add-finalizer! object procedure returns unspecified
     Registers PROCEDURE as the finalizer for OBJECT.  When OBJECT is later about to be reclaimed by the garbage collector, PROCEDURE is applied to one argument, OBJECT.  All finalizers are applied in a child of the root scheduler thread that is spawned after every garbage collection.  If an error occurs in any finalizer, it will be printed to the standard error output port, and all other finalizers will be aborted before they are given a chance to run.  Because of this, and the fact that finalizers are collected and run after every garbage collection, they should perform as little computation as possible.  PROCEDURE may also create new references to OBJECT elsewhere in the heap, in which case the object will not be reclaimed, but its associated finalizer will be forgotten.

     Warning: Finalizers are expensive.  Use sparingly.

 -- Scheme procedure: define-record-resumer record-type resumer returns unspecified
     Identical to the procedure accessible with the same name from the Records, record-types structure.  Record resumers are often useful in working with foreign C data, which is in many cases specific to the program image within the operating system, and which cannot straightforwardly be relocated to a different address space.