gauche.native-type - ネイティブタイプユーティリティ ¶This module provides a type infrastructure to communicate with the “native”, or “close to the metal” layer. Examples include foreign function interface (FFI) and structured binary data access.
Basic native types are built-in (see ネイティブタイプ). This module adds constructors for derived or aggregate types (such as arrays and structs), endian-specified types, conversions between native type objects and compact signatures, and so on.
This module also provides native handles, via which you access native data from Scheme world (see Native handles).
| • Derived and aggregate native types: | ||
| • Representation-specific types: | ||
| • Native type signature: | ||
| • Native handles: |
We have subclasses of <native-type>, which are classes
of individual derived or aggregate native types.
For example, “pointer to int” native type is an instance of
<c-pointer> class. Note that <c-pointer> itself
is not an instance of <native-type>.
A class of native types representing pointers. Can be created
with make-c-pointer-type, or from a signature
with native-type (e.g. (native-type 'int*),
see Native type signature).
Note: At the moment, we don’t keep track of quoalifiers
such as const or volatile, but their support may
be added in future.
A native handle with a C pointer type can be “dereferenced”
with native* (see Native handles).
{gauche.native-type}
The argument must be an native type instance.
Returns an native type represents a pointer to the pointee-type.
(make-c-pointer-type <int>) ⇒ #<c-pointer <int*>> (make-c-pointer-type (make-c-pointer-type <int>)) ⇒ #<c-pointer <int**>>
{gauche.native-type}
Returns the pointee type of the given c-pointer type.
(c-pointer-type-pointee (make-c-pointer-type <int>)) ⇒ #<native-type <int>>
{gauche.native-type}
A class of native types representing C-style arrays. Can be created
with make-c-array-type, or from a signature
with native-type (e.g. (native-type '(.array int (10))),
see Native type signature).
Arrays can have more than one dimensions. Elements
with consectuve last indexes are laid adjacent on memory.
The length of the first dimension can be left unspecified
(we use * as a placeholder), just like C array
such as int a[][10][3].
An element, or a subarray, of an array represented by a
native handle with a C array type
can be accessed with native-aref (see Native handles).
{gauche.native-type}
Creates a C array type, whose elements are of type element-type,
which must be a native type.
The dimensions argument must be a list of non-negative
exact integers, except that the first element may be a symbol *.
They specify the lengths of each dimension of the array. Each index
of dimensions starts with 0. * in the first dimension indicates
the length is unspecified.
{gauche.native-type}
Returns a list of lengths of dimensions of c-array-type.
{gauche.native-type}
A class of native types representing C function types. Can be created
with make-c-function-type, or from a signature
with native-type (e.g.
(native-type '(.function (int int) ::int)),
see Native type signature).
Instances of <c-function> describe the signature of a C function:
its return type, argument types, and whether it accepts variable arguments.
A native handle with a <c-function> type can be cast to and from
a pointer-to-function type with cast-handle
(see Native handles).
{gauche.native-type}
Returns a native type representing a C function that returns
return-type and takes arguments of the types listed in
argument-type-list. Both return-type and each element
of argument-type-list must be native type instances, with
an exception below.
The last element of argument-type-list can be the symbol ...,
and then the resulting type represents a variadic function (like C’s ...
in int printf(const char*, …)). The ... marker is
not a native type and is not included in the result of
c-function-type-argument-types.
(make-c-function-type <int> `(,<int> ,<double>)) ⇒ #<c-function int double -> int> (make-c-function-type <int> `(,<int> ...)) ⇒ #<c-function int ... -> int> (c-function-type-argument-types (make-c-function-type <int> `(,<int> ...))) ⇒ (#<native-type <int>>) (c-function-type-variadic? (make-c-function-type <int> `(,<int> ...))) ⇒ #t
{gauche.native-type}
Returns the return type of c-function-type as a native type instance.
{gauche.native-type}
Returns the list of argument types of c-function-type. Each element
is a native type instance. The variadic marker ... is not included;
use c-function-type-variadic? to check for variadic functions.
{gauche.native-type}
Returns #t if c-function-type represents a variadic function
(i.e., it was created with ... as the last element of the
argument-type list), #f otherwise.
{gauche.native-type}
A class of native types representing C struct and union types, respectively.
Can be created with make-c-struct-type and
make-c-union-type, or from a signature with
native-type (e.g.
(native-type '(.struct t (a::int b::char))),
see Native type signature).
{gauche.native-type}
Returns a native type representing a C struct type or a C union type.
tag can be a symbol representing the struct/union tag, or #f
for untagged struct/union.
fields is a list of (symbol type), where
symbol names the field’s name, and type for its type.
type must be an instance of a native type.
When a struct/union type is constructed, its total size and each field’s offset are computed (in unions, all the offsets are 0).
{gauche.native-type}
Returns the tag (symbol) of c-struct/union-type.
If the type is untagged, #f is returned.
{gauche.native-type}
Returns a list of field names (symbols) of c-struct/union-type.
{gauche.native-type}
Returns the type and the byte offset of field-name (symbol)
of c-struct/union-type.
{gauche.native-type}
Returns #t if obj is an instance of <c-pointer>,
<c-array>, c-function>, c-struct, or <c-union>,
and #f otherwise, respectively.
{gauche.native-type}
Returns #t if obj is either a C pointer type,
a C array type, or a C function type. Handles of those types
can be “casted” to a pointer type, following the C semantics.
See cast-handle for the details (see Native handles).
{gauche.native-type}
Returns #t if obj is either a C array type,
a C struct type, or a C union type.
{gauche.native-type}
Returns #t if obj is either
a C struct type, or a C union type.
Primitive native types such as <int16> read/write memory
with the system’s native endianness. For FFI it is fine. However,
if you read/write binary data for exchanging between systems,
you need to explicitly specify the endianness.
We have native types for that purpose.
{gauche.native-type}
These native types accesses binary data as the specified numeric type,
and the specified endianncess (-be for big-endian,
-le for little endian).
The endianness is only considered when reading from or writing to memory
through native handles (with native* etc, see Native handles).
In other words, these types only makes sense when they are used
within derived or aggregate types.
A native type signature is a compact S-expression description of
a native type. It lets you specify pointer, array, struct, union, and
function types without explicitly calling the corresponding constructors
such as make-c-pointer-type.
The procedure native-type can parse a signature
and returns the native type instance it denotes; native-type->signature
performs the inverse conversion. Signatures are also recognized in
some other places where a native type is expected—for example, in
struct/union field type declarations within .struct and
.union signature forms (so compound types can be written
without first naming each piece).
The signature format has been used in Gauche-C interface for long time (stubs and CiSE), though hasn’t been documented well. Because of its origin to transfer C type declarations to S-expression, it may feel C-centric.
A bare symbol whose name matches a built-in C type name denotes the
corresponding primitive native type. Recognized names follow the
C spelling, e.g. int, u_int, short, u_short,
long, u_long, char, int8_t, uint8_t,
int16_t, uint16_t, int32_t, uint32_t,
int64_t, uint64_t, size_t, ssize_t,
ptrdiff_t, off_t, intptr_t, uintptr_t,
float, double, and void. See ネイティブタイプ
for the corresponding type instances and what Scheme values they accept.
C’s char denotes the native type <c-char>, for
<char> is used for Gauche’s character type. <c-char>
is mapped to a Scheme character with unicode range U+0000 to U+00FF.
If the C routine uses char as a byte-sized numeric value,
use int8_t or uint8_t (depending on signedness) instead.
The pseudo-name c-string denotes the <c-string> type
(NUL-terminated C string). This special name is provided because
C type const char * may simply mean a pointer to byte-sized
numeric data, thus ambiguous.
pThe endian-specified types listed in Representation-specific types
are also accepted, by their underscore-separated names: int16_le,
int16_be, uint16_le, uint16_be, and likewise for
the 32-bit and 64-bit integer types and for float and double.
A symbol whose name ends with one or more asterisks denotes a pointer
type; each trailing asterisk wraps the rest of the type in one
additional layer of <c-pointer>. Thus int* is equivalent
to (make-c-pointer-type <int>), char** is a pointer to a
pointer to <c-char>, and so on.
C-style multi-token forms are also accepted as a list of symbols.
The list is normalized by stripping any const tokens and
concatenating the rest into a single symbol. Therefore
(char *), (char const*), (const char*),
(int * *), and (int** *) are all valid. The form
(const type) is also accepted, with const
currently ignored.
(We do not yet track const or volatile qualifiers on the
resulting native type; they are silently dropped. Support may be added
in the future.)
(.array element-type (dim ...))
Denotes a C-style array. element-type is itself a native type
signature. Each dim is a non-negative exact integer, except
that the leftmost dim may be the symbol * to indicate an
unspecified leading dimension (as in C’s int a[][3][4]).
Multiple dimensions describe a multi-dimensional array, with elements
that share leading indices laid out adjacently in memory (the last
index varies fastest).
(.struct tag (field-spec ...)) (.struct (field-spec ...)) (.union tag (field-spec ...)) (.union (field-spec ...))
Denote a C struct or union type. tag, when given, is a symbol that names the struct/union tag; the second form of each pair (with no tag) denotes an anonymous struct/union.
Each field-spec has the form
name::type, using the typed-variable notation
common across Gauche. name is a symbol naming the field, and
type is itself a native type signature, so fields may be of
compound type as well. For the convenience, the delimiter ::
may be concatenated to name and/or type–
for example, a::int and a :: int are equivalent.
(.function (arg-type ...) return-type) (.function (arg-type ... ...) return-type)
Denotes a C function type. Each arg-type and return-type
is itself a native type signature. If the last arg-type is the
literal symbol ..., the resulting type is variadic
(corresponding to C’s trailing ...); the ... marker is
not itself a type, and is not included in the argument-type list
returned by c-function-type-argument-types. Use
c-function-type-variadic? to test for variadicity.
If the argument is already an instance of <native-type>,
native-type returns it unchanged. This makes it convenient for
higher-level routines to accept either a signature or a previously
constructed type instance.
Notably, you can emulate C’s typedef by assigning native type
to a variable, and inserting it in another type signature:
(define foo (.struct foo (a::int b::int))) (native-type `(.array ,foo (10))) ⇒ #<c-array struct foo(10)>
(native-type 'int) ⇒ #<native-type <int>> (native-type 'int*) ⇒ #<c-pointer <int*>> (native-type 'char**) ⇒ #<c-pointer <c-char**>> (native-type '(char const *)) ⇒ #<c-pointer <c-char*>> (native-type 'c-string) ⇒ #<native-type <c-string>> (native-type '(.array int (3 4))) ⇒ #<c-array <int>(3 4)> (native-type '(.array int (* 3))) ⇒ #<c-array <int>(* 3)> (native-type '(.struct point (x::double y::double))) ⇒ #<c-struct struct point> (native-type '(.union v (i::int f::float))) ⇒ #<c-union union v> (native-type '(.function (int int) double)) ⇒ #<c-function <int> <int> -> <double>> (native-type '(.function (char* ...) int)) ⇒ #<c-function <c-char*> ... -> <int>>
{gauche.native-type}
The argument must be an S-expression type signature or
a native type instance. If it is a type signature, a native
type instance denoted by the type signature is returned.
If the argument is already a native type instance, it is returned
as is.
See above for the specification of a native type signature.
{gauche.native-type}
Returns a native type signature that denotes the given native type.
A native handle is a handle through which you can access native data. Native handles may be returned from a foreign function call, or you can create one from a binary buffer. C pointers, arrays, structs, and unions to be passed to and from foreign functions are reprensed by native handles.
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}
{gauche.native-type}