19.21 Static import expression: _import string : cfunty
This expression allows you to use C functions as SML# functions. The meaning of each component is as follows:
-
•
string: the name of the C function. This is the name that linker recognizes as an external symbol name.
-
•
cfunty: the type of the C function. It must be of the following form.
C function type: cfunty | |||
---|---|---|---|
cfunty | ::= | cfunattr argTyList -> retTyOpt | |
argTyList | ::= | ( argTy,,argTy ,varArgs ) | (multiple arguments) |
argTy | (only one argument) | ||
() | (no argument) | ||
retTyOpt | ::= | retTy | |
() | (void type in C) | ||
callback function type: argfunty | |||
argfunty | ::= | cfunattr retTylist -> argTyOpt | |
retTyList | ::= | ( retTy,,retTy ,varRets ) | (multiple arguments) |
retTy | (only one argument) | ||
() | (no argument) | ||
argTyOpt | ::= | argTy | |
() | (void type in C) | ||
interoperable type: interoperableTy | |||
interoperableTy | ::= | tySeq longTycon | (interoperable types only. See below for details) |
argument type from SML# to C: argTy | |||
argTy | ::= | argTy * * argTy | (types of pointers to a structure) |
{ argTyRow } | (types of pointers to a structure) | ||
tyvar | (boxed kind only) | ||
interoperableTy | |||
argfunty | (callback function argument types) | ||
argTyRow | ::= | lab : argTy , argTyRow | (lab must begin with decimal) |
return type from C to SML#: retTy | |||
retTy | ::= | interoperableTy | |
tyvar | (boxed kind only) | ||
variable-length argument type specification: varArgs and varRets | |||
varArgs | ::= | ... ( argTy,,argTy ) | |
varRets | ::= | ... ( retTy,,retTy ) | |
C function attributes: cfunattr | |||
cfunattr | ::= | __attribute__((attr,,attr)) | |
att | ::= | cdecl stdcall fastcc pure fast |
cfunty indicates the type of the C function in SML#’s type names and type notation. interoperableTy, the type names for C functions, must satisfy both of the following:
-
1.
interoperableTyは以下のいずれかでなければならない.
-
•
Interoperable atomic types: int, int8, int16, int64, word, word8, word16, word64, real, real32, char, or string.
-
•
The types of C pointers: codeptr, interoperableTy ptr, or unit ptr.
-
•
The types of C pointers: tyvar ptr (ただしtyvar must be of either boxed or unboxed kind).
-
•
The types of size: ty size.
-
•
Array types: interoperableTy array, interoperableTy vector, or interoperableTy ref.
-
•
Polymorphic array types: tyvar array, tyvar vector, or tyvar ref (ただしtyvar must be of either boxed or unboxed kind).
-
•
An alias of one of the above types defined by a type declaration. tySeq longTycon must be expanded to one of the above types. If an alias type occurs as an interoperableTy in the context of argTy, tySeq longTycon may be expanded to an tuple or record type that can be regarded as an argTy.
-
•
-
2.
Neither string, array, vector, nor ref may occur as the type of values that would be passed from C to SML# or be overwritten by a C function. In other words, these types must not occur as
-
•
interoperableTy in the context of retTy, and
-
•
the type parameter of array, ref, and ptr type.
-
•
以上の条件を満たすinteroperableTyは, その型名から自然に類推されるCの型に相当する. 対応を以下に示す.
interoperableTy | 対応するCの型 |
---|---|
int and its family | signed integer of the same size |
word and its family | unsigned integer of the same size |
real | double |
real32 | float |
char | char |
string | const char * |
codeptr | pointer to a function |
ptr | pointer to |
unit ptr | void * or pointer to an incomplete type |
size | size_t |
array | pointer to the beginning of an array of |
vector | pointer to the beginning of a vector of |
ref | pointer to an one-element array of |
Note that the size of int and word is always 32 bits. In almost of all modern operating systems, SML#’s int is identical to C’s int, whereas they are not identical in some systems whose int is not 32 bits.
argTy * * argTy and {lab:argTy, , lab:argTy} of argTy corresponds to the type of pointers to a const structure whose members are of type argTy, , argTy in the order of decimal of labels. If all are identical, it also corresponds to a pointer to the beginning of an const array of elements of .
If and only if a C function acts like a parametric polymorphic function from the perspective of SML# programs, it is allowed to use type variables as a C function’s argument or return type. For example, an identical function in C
void *id(void *x) { return x; }
is allowed to be imported like this:
val ’a#boxed id = _import "id" : ’a -> ’a
Another example is printf function that prints an arbitrary pointer value.
val ’a#boxed printPtr = _import "printf" : (string,...(’a)) -> int
The following C function attributes are available:
- cdecl
-
The C function follows the standard calling convention of C functions on the target platform. This is the default if no calling convention is specified through function attributes.
- stdcall
-
The C function follows stdcall calling convention on Windows platforms.
- fastcc
-
The C function follows fastcc calling convention provided by LLVM.
- pure
-
The C function is pure in the sense of SML#. In other words, C functions of this attribute does not perform any memory update and I/O, and its return value is decided only from the list of arguments. This attribute affects the optimization of the SML# compiler.
- fast
-
The C function returns very quickly. It neither execute SML# code through callbacks nor pause the thread execution. The SML# compiler generates efficient invocation code for such functions. Note that, if a C function of this attribute either consumes much time or pause a thread execution, garbage collection would be suspended and consequently all threads would be suspended.
The type of this expression is the SML# function type corresponding to the type specified in cfunty. The correspondence is defined as follows.
C function type | SML# function type |
---|---|
( argTy, , argTy varArgs ) -> retTy | argTy * * argTy * varArgs -> retTy |
() in the argument or return type appear as unit in the SML# type. interoperableTy, tyvar, and * appear in the SML# type without modification. argfunty is interpreted similarly.
The value of this expression is the SML# function that calls the C function specified in string. As long as the C function type specification is correct, this function can be used similarly to ordinary SML# functions.