SML# Document Version 4.1.0
10 SML# feature: direct interface to C

10.2 Declaring types of C functions

C functions that can be imported to SML# are those whose types are representable in SML#. The type in _import declaration is the type of C function written in SML# notation. The variable specified in the val declaration is bound to the imported C function. The type of this variable is an SML# function type that is corresponding to the type of the C function.

A C function type in _import declaration is of the form:

(τ1, τ2, , τn) -> τ

This notation represents a C function that takes n arguments of type τ1,τ2,,τn and returns a value of τ type. Parentheses can be omitted if there is just one argument. What τ is is described below. If there is no argument, write as follows:

() -> τ

If the return type is void in C, write as follows:

(τ1, τ2, , τn) -> ()

If the C function has a variable length argument list, use the following notation:

(τ1, , τm, ...(τm+1, , τn)) -> τ

This is the type of a C function that takes at least m arguments followed by variable number of arguments. Since SML# does not support variable length argument lists, user need to specify the number and types of arguments in the variable length part of the argument list. This notation means that arguments of τm+1, , τn type are passed to the function.

In the argument list and the return type of the above C function type notation, you can specify any SML# type that is corresponding to a C type. In what follows, we refer to such SML# types as interoperable types. The set of interoperable types include the following:

  • Any integer type except IntInf, such as int, word, and char.

  • Any floating-point number type, such as real and Real32.real.

  • Any tuple type whose any field type is an interoperable type, such as int * real.

  • Any vector, array and ref type whose element type is an interoperable type, such as string, Word8Array.array, int ref.

The correspondence between these interoperable types and C types are given as follows:

  • The following table shows the correspondence on integer types and floating-point number types.

    SML#’s interoperable type corresponding C type note
    char char Signedness is not specified, similar to C.
    word8 unsigned char We assume a byte is 8 bit.
    int int Natural size of integers
    word unsigned int
    Real32.real float IEEE754 32-bit floating-point numbers
    real double IEEE754 64-bit floating-point numbers
  • Any τ vector and τ array type is corresponding to the type of a pointer to an array whose element type is the C type corresponding to τ type. The array pointed by an array pointer is mutable. In contrast, that of an vector pointer is immutable. In other words, the element type of an array pointed by an vector pointer is qualified by const qualifier.

  • string type is corresponding to the type of a pointer to an array of const char. The last element of the array pointed by a string pointer is always terminated by a null character. So a string pointer can be regarded as a pointer to a null-terminated string.

  • Any τ ref type is corresponding to the type of a pointer to the C type corresponding to τ. A ref pointer points to a mutable array of just one element.

  • Any tuple type τ1 * * τn is corresponding to the type of a pointer to a immutable structure whose members are τ1,,τn type in this order. If all of τ1,,τn are same type, this tuple type is also corresponding to the type of a pointer to an array.

Values constructed by SML# are passed transparently to C functions without any modification and conversion. So, user can pass an array allocated in SML# program to a C function that modifies the given array, and obtain the modification by the C function in SML# program.

The entire type of a C function is converted to an SML# function type whose argument type is a tuple type of the argument list types of the C function. There is the following limitation in usage of interoperable types in the C function notation:

  • Interoperable types that corresponds to a C pointer type, such as array type and tuple type, cannot be specified as a return type of a C function.