mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-04-29 19:30:36 +02:00
Expose read-c-struct, write-c-struct syntax
* module/system/foreign.scm (read-c-struct): Rename from read-fields. Export. (write-c-struct): Rename from write-fields. Export. (%write-c-struct, %read-c-struct): Add % prefix to these private bindings.
This commit is contained in:
parent
d7ae468c17
commit
e15617dc0e
2 changed files with 63 additions and 21 deletions
|
@ -1,6 +1,6 @@
|
|||
@c -*-texinfo-*-
|
||||
@c This is part of the GNU Guile Reference Manual.
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2007-2014, 2016-2017, 2021
|
||||
@c Copyright (C) 1996, 1997, 2000-2004, 2007-2014, 2016-2017, 2021, 2024
|
||||
@c Free Software Foundation, Inc.
|
||||
@c See the file guile.texi for copying conditions.
|
||||
|
||||
|
@ -761,24 +761,64 @@ also be a list of types, in which case the alignment of a
|
|||
@code{struct} with ABI-conventional packing is returned.
|
||||
@end deffn
|
||||
|
||||
Guile also provides some convenience methods to pack and unpack foreign
|
||||
pointers wrapping C structs.
|
||||
Guile also provides some convenience syntax to efficiently read and
|
||||
write C structs to and from bytevectors.
|
||||
|
||||
@deffn {Scheme Procedure} make-c-struct types vals
|
||||
Create a foreign pointer to a C struct containing @var{vals} with types
|
||||
@code{types}.
|
||||
@deffn {Scheme Syntax} read-c-struct bv offset @* ((field type) @dots{}) k
|
||||
Read a C struct with fields of type @var{type}... from the bytevector
|
||||
@var{bv}, at offset @var{offset}. Bind the fields to the identifiers
|
||||
@var{field}..., and return @code{(@var{k} @var{field} ...)}.
|
||||
|
||||
@var{vals} and @code{types} should be lists of the same length.
|
||||
Unless cross-compiling, the field types are evaluated at macro-expansion
|
||||
time. This allows the resulting bytevector accessors and size/alignment
|
||||
computations to be completely inlined.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} write-c-struct bv offset @* ((field type) @dots{})
|
||||
Write a C struct with fields @var{field}... of type @var{type}... to the bytevector
|
||||
@var{bv}, at offset @var{offset}. Return zero values.
|
||||
|
||||
Like @code{write-c-struct} above, unless cross-compiling, the field
|
||||
types are evaluated at macro-expansion time.
|
||||
@end deffn
|
||||
|
||||
For example, to define a parser and serializer for the equivalent of a
|
||||
@code{struct @{ int64_t a; uint8_t b; @}}, one might do this:
|
||||
|
||||
@example
|
||||
(use-modules (system foreign) (rnrs bytevectors))
|
||||
|
||||
(define-syntax-rule
|
||||
(define-serialization (reader writer) (field type) ...)
|
||||
(begin
|
||||
(define (reader bv offset)
|
||||
(read-c-struct bv offset ((field type) ...) values))
|
||||
(define (writer bv offset field ...)
|
||||
(write-c-struct bv offset ((field type) ...)))))
|
||||
|
||||
(define-serialization (read-struct write-struct)
|
||||
(a int64) (b uint8))
|
||||
|
||||
(define bv (make-bytevector (sizeof (list int64 uint8))))
|
||||
|
||||
(write-struct bv 0 300 43)
|
||||
(call-with-values (lambda () (read-struct bv 0))
|
||||
list)
|
||||
@result{} (300 43)
|
||||
@end example
|
||||
|
||||
There is also an older interface that is mostly equivalent to
|
||||
@code{read-c-struct} and @code{write-c-struct}, but which uses run-time
|
||||
dispatch, and operates on foreign pointers instead of bytevectors.
|
||||
|
||||
@deffn {Scheme Procedure} parse-c-struct foreign types
|
||||
Parse a foreign pointer to a C struct, returning a list of values.
|
||||
|
||||
@code{types} should be a list of C types.
|
||||
@end deffn
|
||||
|
||||
For example, to create and parse the equivalent of a @code{struct @{
|
||||
int64_t a; uint8_t b; @}}:
|
||||
Our parser and serializer example for @code{struct @{ int64_t a; uint8_t
|
||||
b; @}} looks more like this:
|
||||
|
||||
@example
|
||||
(parse-c-struct (make-c-struct (list int64 uint8)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue