▼ |  | FFI: PLT Scheme Foreign Interface

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

► | 6 | Derived Utilities

6.1 | Tagged C Pointer Types
6.2 | Safe C Vectors
6.3 | SRFI-4 Vectors

On this page:

6.1`` Tagged C Pointer Types
_ cpointer
_ cpointer/ null
define-cpointer-type
6.1.1`` Unsafe Tagged C Pointer Functions
cpointer-has-tag?
cpointer-push-tag!
6.2`` Safe C Vectors
make-cvector
cvector
cvector?
cvector-length
cvector-type
cvector-ptr
cvector-ref
cvector-set!
cvector->list
list->cvector
6.2.1`` Unsafe C Vector Construction
make-cvector*
6.3`` SRFI-4 Vectors
make-u8vector
u8vector
u8vector?
u8vector-length
u8vector-ref
u8vector-set!
list->u8vector
u8vector->list
u8vector->cpointer
_ u8vector
make-s8vector
s8vector
s8vector?
s8vector-length
s8vector-ref
s8vector-set!
list->s8vector
s8vector->list
s8vector->cpointer
_ s8vector
make-s16vector
s16vector
s16vector?
s16vector-length
s16vector-ref
s16vector-set!
list->s16vector
s16vector->list
s16vector->cpointer
_ s16vector
make-u16vector
u16vector
u16vector?
u16vector-length
u16vector-ref
u16vector-set!
list->u16vector
u16vector->list
u16vector->cpointer
_ u16vector
make-s32vector
s32vector
s32vector?
s32vector-length
s32vector-ref
s32vector-set!
list->s32vector
s32vector->list
s32vector->cpointer
_ s32vector
make-u32vector
u32vector
u32vector?
u32vector-length
u32vector-ref
u32vector-set!
list->u32vector
u32vector->list
u32vector->cpointer
_ u32vector
make-s64vector
s64vector
s64vector?
s64vector-length
s64vector-ref
s64vector-set!
list->s64vector
s64vector->list
s64vector->cpointer
_ s64vector
make-u64vector
u64vector
u64vector?
u64vector-length
u64vector-ref
u64vector-set!
list->u64vector
u64vector->list
u64vector->cpointer
_ u64vector
make-f32vector
f32vector
f32vector?
f32vector-length
f32vector-ref
f32vector-set!
list->f32vector
f32vector->list
f32vector->cpointer
_ f32vector
make-f64vector
f64vector
f64vector?
f64vector-length
f64vector-ref
f64vector-set!
list->f64vector
f64vector->list
f64vector->cpointer
_ f64vector

top← prev up next →

### 6`` Derived Utilities

#### 6.1`` Tagged C Pointer Types

The unsafe cpointer-has-tag? and cpointer-push-tag! operations manage tags to distinguish pointer types.

(_cpointer |  | tag |  |  |  |
| [ | ptr-type |  |  |  |
|  | scheme-to-c |  |  |  |
|  | c-to-scheme]) |  | → |  | ctype

tag : any/c
ptr-type : ctype? = xpointer
scheme-to-c : (any/c . -> . any/c) = values
c-to-scheme : (any/c . -> . any/c) = values

(_cpointer/null |  | tag |  |  |  |
| [ | ptr-type |  |  |  |
|  | scheme-to-c |  |  |  |
|  | c-to-scheme]) |  | → |  | ctype

tag : any/c
ptr-type : ctype? = xpointer
scheme-to-c : (any/c . -> . any/c) = values
c-to-scheme : (any/c . -> . any/c) = values

Construct a kind of a pointer that gets a specific tag when converted to Scheme, and accept only such tagged pointers when going to C. An optional ptr-type can be given to be used as the base pointer type, instead of _pointer.

Pointer tags are checked with cpointer-has-tag? and changed with cpointer-push-tag! which means that other tags are preserved. Specifically, if a base ptr-type is given and is itself a _cpointer, then the new type will handle pointers that have the new tag in addition to ptr-type’s tag(s). When the tag is a pair, its first value is used for printing, so the most recently pushed tag which corresponds to the inheriting type will be displayed.

Note that tags are compared with eq? (or memq), which means an interface can hide its value from users (e.g., not provide the cpointer-tag accessor), which makes such pointers un-fake-able.

_cpointer/null is similar to _cpointer except that it tolerates NULL pointers both going to C and back. Note that NULL pointers are represented as #f in Scheme, so they are not tagged.

(define-cpointer-type _id)
(define-cpointer-type _id scheme-to-c-expr)
(define-cpointer-type _id scheme-to-c-expr c-to-scheme-expr)

A macro version of _cpointer and _cpointer/null, using the defined name for a tag string, and defining a predicate too. The _id must start with _.

The optional expression produces optional arguments to _cpointer.

In addition to defining _id to a type generated by _cpointer, _id/null is bound to a type produced by _cpointer/null type. Finally, id? is defined as a predicate, and id-tag is defined as an accessor to obtain a tag. The tag is the string form of id.

##### 6.1.1`` Unsafe Tagged C Pointer Functions

(cpointer-has-tag? cptr tag) → boolean?
cptr : any/c
tag : any/c
(cpointer-push-tag! cptr tag) → void
cptr : any/c
tag : any/c

These two functions treat pointer tags as lists of tags. As described in Pointer Functions, a pointer tag does not have any role, except for Scheme code that uses it to distinguish pointers; these functions treat the tag value as a list of tags, which makes it possible to construct pointer types that can be treated as other pointer types, mainly for implementing inheritance via upcasts (when a struct contains a super struct as its first element).

The cpointer-has-tag? function checks whether if the given cptr has the tag. A pointer has a tag tag when its tag is either eq? to tag or a list that contains (in the sense of memq) tag.

The cpointer-push-tag! function pushes the given tag value on cptr’s tags. The main properties of this operation are: (a) pushing any tag will make later calls to cpointer-has-tag? succeed with this tag, and (b) the pushed tag will be used when printing the pointer (until a new value is pushed). Technically, pushing a tag will simply set it if there is no tag set, otherwise push it on an existing list or an existing value (treated as a single-element list).

#### 6.2`` Safe C Vectors

The cvector form can be used as a type C vectors (i.e., a pointer to a memory block).

(make-cvector type length) → cvector?
type : ctype?
length : exact-nonnegative-integer?

Allocates a C vector using the given type and length.

(cvector type val ...) → cvector?
type : ctype?
val : any/c

Creates a C vector of the given type, initialized to the given list of vals.

(cvector? v) → boolean?
v : any/c

Returns #t if v is a C vector, #f otherwise.

(cvector-length cvec) → exact-nonnegative-integer?
cvec : cvector?

Returns the length of a C vector.

(cvector-type cvec) → ctype?
cvec : cvector?

Returns the C type object of a C vector.

(cvector-ptr cvec) → cpointer?
cvec : cvector?

Returns the pointer that points at the beginning block of the given C vector.

(cvector-ref cvec k) → any
cvec : cvector?
k : exact-nonnegative-integer?

References the kth element of the cvec C vector. The result has the type that the C vector uses.

(cvector-set! cvec k val) → void?
cvec : cvector?
k : exact-nonnegative-integer?
val : any

Sets the kth element of the cvec C vector to val. The val argument should be a value that can be used with the type that the C vector uses.

(cvector->list cvec) → list?
cvec : cvector?

Converts the cvec C vector object to a list of values.

(list->cvector lst type) → cvector?
lst : list?
type : ctype?

Converts the list lst to a C vector of the given type.

##### 6.2.1`` Unsafe C Vector Construction

(make-cvector* cptr type length) → cvector?
cptr : any/c
type : ctype?
length : exact-nonnegative-integer?

Constructs a C vector using an existing pointer object. This operation is not safe, so it is intended to be used in specific situations where the type and length are known.

#### 6.3`` SRFI-4 Vectors

SRFI-4 vectors are similar to C vectors (see Safe C Vectors), except that they define different types of vectors, each with a hard-wired type.

An exception is the u8 family of bindings, which are just aliases for byte-string bindings: make-u8vector, u8vector. u8vector?, u8vector-length, u8vector-ref, u8vector-set!, list->u8vector, u8vector->list.

(make-u8vector len) → u8vector?
len : exact-nonnegative-integer?
(u8vector val ...) → u8vector?
val : number?
(u8vector? v) → boolean?
v : any/c
(u8vector-length vec) → exact-nonnegative-integer?
vec : u8vector?
(u8vector-ref vec k) → number?
vec : u8vector?
k : exact-nonnegative-integer?
(u8vector-set! vec k val) → void?
vec : u8vector?
k : exact-nonnegative-integer?
val : number?
(list->u8vector lst) → u8vector?
lst : (listof number?)
(u8vector->list vec) → (listof number?)
vec : u8vector?
(u8vector->cpointer vec) → cpointer?
vec : u8vector?

Like _cvector, but for vectors of _byte elements. These are aliases for byte operations.

(_u8vector mode maybe-len)
_u8vector

Like _cvector, but for vectors of _uint8 elements.

(make-s8vector len) → s8vector?
len : exact-nonnegative-integer?
(s8vector val ...) → s8vector?
val : number?
(s8vector? v) → boolean?
v : any/c
(s8vector-length vec) → exact-nonnegative-integer?
vec : s8vector?
(s8vector-ref vec k) → number?
vec : s8vector?
k : exact-nonnegative-integer?
(s8vector-set! vec k val) → void?
vec : s8vector?
k : exact-nonnegative-integer?
val : number?
(list->s8vector lst) → s8vector?
lst : (listof number?)
(s8vector->list vec) → (listof number?)
vec : s8vector?
(s8vector->cpointer vec) → cpointer?
vec : s8vector?

Like make-vector, etc., but for _int8 elements.

(_s8vector mode maybe-len)
_s8vector

Like _cvector, but for vectors of _int8 elements.

(make-s16vector len) → s16vector?
len : exact-nonnegative-integer?
(s16vector val ...) → s16vector?
val : number?
(s16vector? v) → boolean?
v : any/c
(s16vector-length vec) → exact-nonnegative-integer?
vec : s16vector?
(s16vector-ref vec k) → number?
vec : s16vector?
k : exact-nonnegative-integer?
(s16vector-set! vec k val) → void?
vec : s16vector?
k : exact-nonnegative-integer?
val : number?
(list->s16vector lst) → s16vector?
lst : (listof number?)
(s16vector->list vec) → (listof number?)
vec : s16vector?
(s16vector->cpointer vec) → cpointer?
vec : s16vector?

Like make-vector, etc., but for _int16 elements.

(_s16vector mode maybe-len)
_s16vector

Like _cvector, but for vectors of _int16 elements.

(make-u16vector len) → u16vector?
len : exact-nonnegative-integer?
(u16vector val ...) → u16vector?
val : number?
(u16vector? v) → boolean?
v : any/c
(u16vector-length vec) → exact-nonnegative-integer?
vec : u16vector?
(u16vector-ref vec k) → number?
vec : u16vector?
k : exact-nonnegative-integer?
(u16vector-set! vec k val) → void?
vec : u16vector?
k : exact-nonnegative-integer?
val : number?
(list->u16vector lst) → u16vector?
lst : (listof number?)
(u16vector->list vec) → (listof number?)
vec : u16vector?
(u16vector->cpointer vec) → cpointer?
vec : u16vector?

Like make-vector, etc., but for _uint16 elements.

(_u16vector mode maybe-len)
_u16vector

Like _cvector, but for vectors of _uint16 elements.

(make-s32vector len) → s32vector?
len : exact-nonnegative-integer?
(s32vector val ...) → s32vector?
val : number?
(s32vector? v) → boolean?
v : any/c
(s32vector-length vec) → exact-nonnegative-integer?
vec : s32vector?
(s32vector-ref vec k) → number?
vec : s32vector?
k : exact-nonnegative-integer?
(s32vector-set! vec k val) → void?
vec : s32vector?
k : exact-nonnegative-integer?
val : number?
(list->s32vector lst) → s32vector?
lst : (listof number?)
(s32vector->list vec) → (listof number?)
vec : s32vector?
(s32vector->cpointer vec) → cpointer?
vec : s32vector?

Like make-vector, etc., but for _int32 elements.

(_s32vector mode maybe-len)
_s32vector

Like _cvector, but for vectors of _int32 elements.

(make-u32vector len) → u32vector?
len : exact-nonnegative-integer?
(u32vector val ...) → u32vector?
val : number?
(u32vector? v) → boolean?
v : any/c
(u32vector-length vec) → exact-nonnegative-integer?
vec : u32vector?
(u32vector-ref vec k) → number?
vec : u32vector?
k : exact-nonnegative-integer?
(u32vector-set! vec k val) → void?
vec : u32vector?
k : exact-nonnegative-integer?
val : number?
(list->u32vector lst) → u32vector?
lst : (listof number?)
(u32vector->list vec) → (listof number?)
vec : u32vector?
(u32vector->cpointer vec) → cpointer?
vec : u32vector?

Like make-vector, etc., but for _uint32 elements.

(_u32vector mode maybe-len)
_u32vector

Like _cvector, but for vectors of _uint32 elements.

(make-s64vector len) → s64vector?
len : exact-nonnegative-integer?
(s64vector val ...) → s64vector?
val : number?
(s64vector? v) → boolean?
v : any/c
(s64vector-length vec) → exact-nonnegative-integer?
vec : s64vector?
(s64vector-ref vec k) → number?
vec : s64vector?
k : exact-nonnegative-integer?
(s64vector-set! vec k val) → void?
vec : s64vector?
k : exact-nonnegative-integer?
val : number?
(list->s64vector lst) → s64vector?
lst : (listof number?)
(s64vector->list vec) → (listof number?)
vec : s64vector?
(s64vector->cpointer vec) → cpointer?
vec : s64vector?

Like make-vector, etc., but for _int64 elements.

(_s64vector mode maybe-len)
_s64vector

Like _cvector, but for vectors of _int64 elements.

(make-u64vector len) → u64vector?
len : exact-nonnegative-integer?
(u64vector val ...) → u64vector?
val : number?
(u64vector? v) → boolean?
v : any/c
(u64vector-length vec) → exact-nonnegative-integer?
vec : u64vector?
(u64vector-ref vec k) → number?
vec : u64vector?
k : exact-nonnegative-integer?
(u64vector-set! vec k val) → void?
vec : u64vector?
k : exact-nonnegative-integer?
val : number?
(list->u64vector lst) → u64vector?
lst : (listof number?)
(u64vector->list vec) → (listof number?)
vec : u64vector?
(u64vector->cpointer vec) → cpointer?
vec : u64vector?

Like make-vector, etc., but for _uint64 elements.

(_u64vector mode maybe-len)
_u64vector

Like _cvector, but for vectors of _uint64 elements.

(make-f32vector len) → f32vector?
len : exact-nonnegative-integer?
(f32vector val ...) → f32vector?
val : number?
(f32vector? v) → boolean?
v : any/c
(f32vector-length vec) → exact-nonnegative-integer?
vec : f32vector?
(f32vector-ref vec k) → number?
vec : f32vector?
k : exact-nonnegative-integer?
(f32vector-set! vec k val) → void?
vec : f32vector?
k : exact-nonnegative-integer?
val : number?
(list->f32vector lst) → f32vector?
lst : (listof number?)
(f32vector->list vec) → (listof number?)
vec : f32vector?
(f32vector->cpointer vec) → cpointer?
vec : f32vector?

Like make-vector, etc., but for _float elements.

(_f32vector mode maybe-len)
_f32vector

Like _cvector, but for vectors of _float elements.

(make-f64vector len) → f64vector?
len : exact-nonnegative-integer?
(f64vector val ...) → f64vector?
val : number?
(f64vector? v) → boolean?
v : any/c
(f64vector-length vec) → exact-nonnegative-integer?
vec : f64vector?
(f64vector-ref vec k) → number?
vec : f64vector?
k : exact-nonnegative-integer?
(f64vector-set! vec k val) → void?
vec : f64vector?
k : exact-nonnegative-integer?
val : number?
(list->f64vector lst) → f64vector?
lst : (listof number?)
(f64vector->list vec) → (listof number?)
vec : f64vector?
(f64vector->cpointer vec) → cpointer?
vec : f64vector?

Like make-vector, etc., but for _double* elements.

(_f64vector mode maybe-len)
_f64vector

Like _cvector, but for vectors of _double* elements.
top← prev up next →