Next: Windows Foreign Procedures, Previous: Foreign function interface, Up: Foreign function interface
Foreign types are designed to represent a correspondence between a Scheme data type that is used to represent an object within the Scheme world and a C data type that represents the data object in the C world. Thus we cannot manipulate true C objects in Scheme, nor can we manipulate Scheme objects in C.
Each foreign type has four aspects that together ensure that the correspondence between the Scheme and C objects is maintained. These aspects are all encoded as procedures that either check for validity or convert between representations. Thus a foreign type is not a declarative type so much as a procedural description of how to pass the type. The underlying foreign procedure call mechanism can pass integers and vector-like Scheme objects, and returns integer values. All other objects must be translated into integers or some other basic type, and must be recovered from integers.
The aspects are:
#t
if the argument is of an acceptable
Scheme type, otherwise returns #f
.
The check procedure is used for type-checking.
Both forms define a windows type. The first form defines a type in terms of its aspects as described above. The second defines the type as being like another type, except for certain aspects, which are redefined. Name is the name of the type. Model is the name of a type. Check, convert, return and revert are procedures or the value
#f
. A#f
means use the default value, which in the second form means use the definition provided for model. The defaults are
- check
(lambda (x) #t)
, i.e. unchecked.- convert
(lambda (x) x)
, i.e. no translation performed.- return
(lambda (x) x)
, i.e. no translation performed.- revert
(lambda (x y) unspecific)
, i.e. no update performedThe
unchecked
windows type (see below) is defined as:(define-windows-type unchecked #f #f #f #f)Windows types are not first class values, so they cannot be stored in variables or defined using
define
:(define my-type unchecked) error--> Unbound variable (define-similar-windows-type my-type unchecked) ;; the correct way
Scheme characters must be converted to integers. This is accomplished as follows:
(define-windows-type char char? ; check char->integer ; convert integer->char ; convert return value #f ; cannot be passed by reference )
The type which is not checked and undergoes only the basic conversion from a Scheme integer to a C integer or from a Scheme string to a C pointer to the first byte of the string. Returned
unchecked
values are returned as integers.
Scheme booleans are analogous to C integers
0
and1
. Windows typebool
have been defined as:(define-windows-type bool boolean? (lambda (x) (if x 1 0)) (lambda (x) (if (eq? x 0) #f #t)) #f)
Scheme characters are converted into C objects of type
char
, which are indistinguishable from small integers.
Various integer types that are passed without conversion.
A string that is passed as a C pointer of type
char*
to the first character in the string.
A string or
#f
. The string is passed as a pointer to characters. The string is correctly null-terminated.#f
is passed as the null pointer. This is an example where there is a more complex mapping between C objects and Scheme objects. C'schar*
type is represented as one of two Scheme types depending on its value. This allows us us to distinguish between the C string (pointer) that points to the empty sequence of characters and the null pointer (which doesnt point anywhere).
Various kinds of Win32 handle. These names correspond to the same, but all uppercase, names in the Windows C language header files. Win32 API calls are the source of values of this type and the values are meaningless except as arguments to other Win32 API calls. Currently these values are represented as integers but we expect that Win32 handles will in future be represented by allocated Scheme objects (e.g. records) that will allow predicates (e.g.
hmenu?
) and sensible interlocking with the garbage collector to free the programmer of the current tedious allocation and deallocation of handles.
A Windows resource identifier is either a small integer or a string. In C, this distinction is possible because pointers look like larger integers, so a machine word representing a small integer can be distinguished from a machine word that is a pointer to the text of the name of the resource.