Interoperable Types

We call a data type that can be directly passed to C an interoperqable type. The current set of interoperable types is given by the syntax.

ity ::= scalar | real | float | string | ity * ... * ity | ity array

In addition, SML# allows higher-order functions to be passed to C and back. The set of allowable types of arguments to _import and _ffiapply are given below.

ty  ::= ity | ty -> ty

When a function is specified, SML# compiler automatically decompose it to a code that exchange atomic data based on the algorithm given in Ohori&KatoPOPL93 So the programmer need only give a function with its type as an argument.

We describe each of the interoperable types below.

scalar values (scalar)

One word scalar (non pointer) value types are all interoperable types. Typical ones include the following C types: long, int, char. In SML#, they correspond to int, char, datatypes with no argument such as bool.

floating point data(real, float)

floating point data supported by the underlying archtecture are interoperable types.

In SML#, real is 64 bit floating point data, and corresponds to double in C.

In addition, SML# support 1 word floating point data of type float, which corresponds to float in C.

strings (string)

SML# string type is interoperable and corresponds to char* in C.

Arrays (ity array)

'a array in SML# is interoperable if 'a is interoperable type. For example,

 A : real array

in SML#' corresponds to

double A[]
double *A

in C.

Tupes and Records (ity * ... * ity)

Tuple types conposed of interoperable element types are inteoperable types, and correspond to struct in C.

In SML#, a labeled record is implemented as a tuple sorted by its labels. Under this interpretation, labeled record types are treated as interoperable types.

For example, a function declared in C as:

struct S {int x; char y;};
int f(struct S* s);

can be used from SML# as follows.

val f = DynamicLink.dlsym(libFoo, "f") : _import (int * char) -> int;

Struct containing floating point numbers can also be treated similarly. A C function of type

struct S {double x; double y;};
int f(struct S* s);

can be used as folloows:

val f = DynamicLink.dlsym(libFoo, "f") : _import (real * real) -> int;

Outmost function types(ity -> ty)

A function type with interoperable argument types and result type can be given to an argument to C function or received from C function. Using this feature, one can easily use C callback mechanism. However, function type cannot appear as a component type to other interoperable types such as arrays or tuples.

Last modified:2007/03/29 13:33:38
References:[Foreign Function Binding] [_Ffiapply special form]