1 Overview
2 Loading Foreign Libraries
3 C Types
4 Pointer Functions
5 Miscellaneous Support
6 Derived Utilities
7 Unexported Primitive Functions
8 Macros for Unsafety
Index
On this page:
_ cprocedure
_ fun
3.6.1 Custom Function Types
define-fun-syntax
_ ?
_ ptr
_ box
_ list
_ vector
_ bytes
_ cvector
Version: 4.0.2

 

3.6 Function Types

(_cprocedure

 

input-types

 

 

 

 

 

 

output-type

 

 

 

 

 

 [

wrapper])

 

 

any

  input-types : (list ctype?)

  output-type : ctype?

  wrapper : (or false/c (procedure? . -> . procedure?)) = #f

A type constructor that creates a new function type, which is specified by the given input-types list and output-type. Usually, the _fun syntax (described below) should be used instead, since it manages a wide range of complicated cases.

The resulting type can be used to reference foreign functions (usually ffi-objs, but any pointer object can be referenced with this type), generating a matching foreign callout object. Such objects are new primitive procedure objects that can be used like any other Scheme procedure.

A type created with _cprocedure can also be used for passing Scheme procedures to foreign functions, which will generate a foreign function pointer that calls the given Scheme procedure when it is used. There are no restrictions on the Scheme procedure; in particular, its lexical context is properly preserved.

The optional wrapper-proc, if provided, is expected to be a function that can change a callout procedure: when a callout is generated, the wrapper is applied on the newly created primitive procedure, and its result is used as the new function. Thus, wrapper-proc is a hook that can perform various argument manipulations before the foreign function is invoked, and return different results (for example, grabbing a value stored in an `output’ pointer and returning multiple values). It can also be used for callbacks, as an additional layer that tweaks arguments from the foreign code before they reach the Scheme procedure, and possibly changes the result values too.

(_fun maybe-args type-spec ... -> type-spec maybe-wrapper)

 

maybe-args

 

=

 

 

 

|

 

(id ...) ::

 

 

|

 

id ::

 

 

|

 

(id ... . id) ::

 

 

 

 

 

type-spec

 

=

 

type-expr

 

 

|

 

(id : type-expr)

 

 

|

 

(type-expr = value-expr)

 

 

|

 

(id : type-expr = value-expr)

 

 

 

 

 

maybe-wrapper

 

=

 

 

 

|

 

-> output-expr

Creates a new function type. The _fun form is a convenient syntax for the _cprocedure type constructor. In its simplest form, only the input type-exprs and the output type-expr are specified, and each types is a simple expression, which creates a straightforward function type.

In its full form, the _fun syntax provides an IDL-like language that can be used to create a wrapper function around the primitive foreign function. These wrappers can implement complex foreign interfaces given simple specifications. The full form of each of the type specifications can include an optional label and an expression. If a = value-expr is provided, then the resulting function will be a wrapper that calculates the argument for that position itself, meaning that it does not expect an argument for that position. The expression can use previous arguments if they were labeled with id :. In addition, the result of a function call need not be the value returned from the foreign call: if the optional output-expr is specified, or if an expression is provided for the output type, then this specifies an expression that will be used as a return value. This expression can use any of the previous labels, including a label given for the output which can be used to access the actual foreign return value.

In rare cases where complete control over the input arguments is needed, the wrapper’s argument list can be specified as args, in any form (including a `rest’ argument). Identifiers in this place are related to type labels, so if an argument is there is no need to use an expression.

For example,

  (_fun (n s) :: (s : _string) (n : _int) -> _int)

specifies a function that receives an integer and a string, but the foreign function receives the string first.

3.6.1 Custom Function Types

The behavior of the _fun type can be customized via custom function types, which are pieces of syntax that can behave as C types and C type constructors, but they can interact with function calls in several ways that are not possible otherwise. When the _fun form is expanded, it tries to expand each of the given type expressions, and ones that expand to certain keyword-value lists interact with the generation of the foreign function wrapper. This expansion makes it possible to construct a single wrapper function, avoiding the costs involved in compositions of higher-order functions.

Custom function types are macros that expand to a sequence (key: val ...), where each key: is from a short list of known keys. Each key interacts with generated wrapper functions in a different way, which affects how its corresponding argument is treated:

The pre: and post: bindings can be of the form (id => expr) to use the existing value. Note that if the pre: expression is not (id => expr), then it means that there is no input for this argument to the _fun-generated procedure. Also note that if a custom type is used as an output type of a function, then only the post: code is used.

Most custom types are meaningful only in a _fun context, and will raise a syntax error if used elsewhere. A few such types can be used in non-_fun contexts: types which use only type:, pre:, post:, and no others. Such custom types can be used outside a _fun by expanding them into a usage of make-ctype, using other keywords makes this impossible, because it means that the type has specific interaction with a function call.

(define-fun-syntax id transformer-expr)

Binds id as a custom function type. The type is expanded by applying the procedure produced by transformer-expr to a use of the custom function type.

_?

A custom function type that is a marker for expressions that should not be sent to the foreign function. Use this to bind local values in a computation that is part of an ffi wrapper interface, or to specify wrapper arguments that are not sent to the foreign function (e.g., an argument that is used for processing the foreign output).

(_ptr mode type-expr)

 

mode

 

=

 

i

 

 

|

 

o

 

 

|

 

io

Creates a C pointer type, where mode indicates input or output pointers (or both). The mode can be one of the following:

For example, the _ptr type can be used in output mode to create a foreign function wrapper that returns more than a single argument. The following type:

  (_fun (i : (_ptr o _int))

        -> (d : _double)

        -> (values d i))

creates a function that calls the foreign function with a fresh integer pointer, and use the value that is placed there as a second return value.

_box

A custom function type similar to a (_ptr io type) argument, where the input is expected to be a box holding an appropriate value, which is unboxed on entry and modified accordingly on exit.

(_list mode type maybe-len)

 

mode

 

=

 

i

 

 

|

 

o

 

 

|

 

io

 

 

 

 

 

maybe-len

 

=

 

 

 

|

 

len-expr

A custom function type that is similar to _ptr, except that it is used for converting lists to/from C vectors. The optional len argument is needed for output values where it is used in the post code, and in the pre code of an output mode to allocate the block. In either case, it can refer to a previous binding for the length of the list which the C function will most likely require.

(_vector mode type maybe-len)

A custom function type like _list, except that it uses Scheme vectors instead of lists.

(_bytes o len-expr)

_bytes

A custom function type that can be used by itself as a simple type for a byte string as a C pointer. Alternatively, the second form is for a pointer return value, where the size should be explicitly specified.

There is no need for other modes: input or input/output would be just like _bytes, since the string carries its size information (there is no real need for the o part of the syntax, but it is present for consistency with the above macros).

(_cvector mode type maybe-len)

_cvector

Like _bytes, _cvector can be used as a simple type that corresponds to a pointer that is managed as a safe C vector on the Scheme side; see Safe C Vectors. The longer form behaves similarly to the _list and _vector custom types, except that _cvector is more efficient; no Scheme list or vector is needed.