(ypsilon c-types) — C data types interface
(define-c-typedef <alias-name> <type-name>)
syntax
- Defines an alias type name
<alias-name>
for an existing type<type-name>
. - This syntax has an analogy to the C typedef statement.
(import (rnrs) (ypsilon c-types)) (define-c-typedef time_t int64_t) ; 64-bit Linux
(define-c-typedef <type-name> (struct (<field-type> <field-name>) ...))
syntax
- Defines a C structure data type
<type-name>
. - This syntax has an analogy to the C typedef statement.
- Valid field data types are
void
bool
char
short
int
long
long-long
unsigned-short
unsigned-int
unsigned-long
unsigned-long-long
int8_t
int16_t
int32_t
inst64_t
uint8_t
uint16_t
uint32_t
uint64_t
float
double
size_t
void*
, and any type names defined bydefine-c-typedef
.
(import (rnrs) (ypsilon c-types)) (define-c-typedef point (struct (int x) (int y))) point ;=> #<c-typedef point 8 4 (struct (int x) (int y))> (define-c-typedef rectangle (struct (point top-left) (point bottom-right))) rectangle ;=> #<c-typedef rectangle 16 4 (struct (point top-left) (point bottom-right))>
(define-c-struct-methods <type-name> ...)
syntax
- Defines a constructor, accessors, and mutators for a C structure data type
<type-name>
. - The constructor’s name is generated by appending
make-
and<type-name>
. - Each accessor’s name is generated by appending
<type-name>
,-
, and<field-name>
. - Each mutator’s name is generated by appending
<type-name>
,-
,<field-name>
, and-set!
.
(import (rnrs) (ypsilon c-types)) (define-c-typedef point (struct (int x) (int y))) (define-c-struct-methods point) (define pt (make-point)) pt ;=> #u8(0 0 0 0 0 0 0 0) (point-x-set! pt 1000) (point-y-set! pt -500) pt ;=> #u8(232 3 0 0 12 254 255 255) (point-x pt) ;=> 1000 (point-y pt) ;=> -500 (define-c-typedef rectangle (struct (point top-left) (point bottom-right))) (define-c-struct-methods rectangle) (define rect (make-rectangle)) (rectangle-bottom-right-set! rect pt) rect ;=> #u8(0 0 0 0 0 0 0 0 232 3 0 0 12 254 255 255) (point-y (rectangle-bottom-right rect)) ;=> -500
- Methods defined in
define-c-struct-methods
are macros to minimize overhead. - For example,
(point-y-set! pt -500)
is a macro and it expandeds to(bytevector-c-int-set! pt 4 -500)
inplace.
(define-c-enum <enumerators> ...)
syntax
- Defines a C enumeration constant.
- This syntax has an analogy to the C enum statement.
<enumerators>
are either an identifier or a subform —(identifier . integer)
.
(import (rnrs) (ypsilon c-types)) (define-c-enum FOO (BAR . 10) BAZ) (list FOO BAR BAZ) ;=> (0 10 11)
(c-sizeof <type-name>)
syntax
- Returns a byte size of C primitives or C structure types.
(import (ypsilon c-types)) (c-sizeof unsigned-int) ;=> 4 (define-c-typedef foo (struct (int8_t u8) (int32_t u32))) (c-sizeof foo) ;=> 8
(make-bytevector-mapping <address> <bytesize>)
procedure
- Provides transparent access to an arbitrary memory block.
make-bytevector-mapping
returns a bytevector-mapping object that can be used as an ordinary bytevector.- Contents of bytevector-mapping object is mapped to the memory block within the range of
<address>
to<address> + <bytesize> - 1
. - Be aware that misuse of bytevector-mapping object causes a fatal error such as a segmentation fault.
(import (rnrs) (ypsilon c-ffi) (ypsilon c-types)) (define comparison (c-callback int (void* void*) (lambda (a1 a2) (let ((n1 (bytevector-c-uint32-ref (make-bytevector-mapping a1 4) 0)) (n2 (bytevector-c-uint32-ref (make-bytevector-mapping a2 4) 0))) (cond ((= n1 n2) 0) ((< n1 n2) 1) (else -1)))))) (define qsort (c-function void qsort (void* int int void*))) (define nums (uint-list->bytevector '(10000 1000 10 100000 100) (native-endianness) 4)) (qsort nums 5 4 comparison) (bytevector->uint-list nums (native-endianness) 4) ;=> (100000 10000 1000 100 10))
(bytevector-mapping? <obj>)
procedure
- Returns
#t
if<obj>
is a bytevector-mapping object, and otherwise returns#f
.
(bytevector->pinned-c-void* <bytevector>)
procedure
- Returns an address of the first element in
<bytevector>
. <bytevector>
is marked ‘pinned’ and its address is preserved during heap compaction.bytevector->pinned-c-void*
is useful if the callee retains the passed pointer.- Be aware that misuse of this procedure causes a fatal error such as a segmentation fault.
(import (rnrs) (ypsilon c-types) (only (core) collect)) (define bv (make-bytevector 8)) bv ;=> #u8(0 0 0 0 0 0 0 0) (define adrs (bytevector->pinned-c-void* bv)) adrs ;=> 105553164664832 (define bv-mapping (make-bytevector-mapping adrs 8)) bv-mapping ;=> #<bytevector-mapping 0x2e28000 8> (bytevector-c-int64-set! bv 0 100000) (bytevector-c-int64-ref bv-mapping 0) ;=> 100000
(make-c-string <string>)
procedure
- Returns a new bytevector containing a C string.
(import (rnrs) (ypsilon c-types)) (make-c-string "foo") ;=> #u8(102 111 111 0)
(bytevector-c-strlen <bytevector>)
procedure
- Returns the length of the C string stored in
<bytevector>
.
(import (rnrs) (ypsilon c-types)) (define bv (make-c-string "foo")) (bytevector-c-strlen bv) ;=> 3
(bytevector-c-{type}-ref <bytevector> <byteindex>)
procedure
- Retrieves a C value from a bytevector
{type}
is eitherbool
char
short
int
long
long-long
unsigned-short
unsigned-int
unsigned-long
unsigned-long-long
int8_t
int16_t
int32_t
inst64_t
uint8_t
uint16_t
uint32_t
uint64_t
float
double
void*
.
(import (rnrs) (ypsilon c-types)) (define bv (u8-list->bytevector '(255 254 253 252 251 250 249 248))) bv ;=> #u8(255 254 253 252 251 250 249 248) (bytevector-c-bool-ref bv 0) ;=> 1 (bytevector-c-int-ref bv 0) ;=> -50462977 (bytevector-c-unsigned-int-ref bv 0) ;=> 4244504319
(bytevector-c-{type}-set! <bytevector> <byteindex> <value>)
procedure
- Stores a C value to a bytevector
{type}
is eitherbool
char
short
int
long
long-long
int8_t
int16_t
int32_t
int64_t
float
double
void*
.- These procedures accept unsigned values if they are within expected interval, like a C type casting between unsigned and signed types.
(import (rnrs) (ypsilon c-types)) (define bv (make-bytevector 2)) (bytevector-c-int16-set! bv 0 65535) ; 0xffff (bytevector-c-int16-ref bv 0) ;=> -1 (0xffff) (bytevector-c-uint16-ref bv 0) ;=> 65535 (0xffff) (bytevector-c-int16-set! bv 0 65536) ; 0x10000 ;=> error in bytevector-c-int16-set!: value out of range, 65536, as argument 3
(make-c-{type} <value>)
procedure
- Returns a new bytevector containing a C value.
{type}
is eitherbool
char
short
int
long
long-long
int8_t
int16_t
int32_t
int64_t
float
double
void*
.
(c-{type}-ref <location>)
procedure
- Retrieves a C value from a bytevector or memory.
<location>
is either a bytevector or a memory address.{type}
is eitherbool
char
short
int
long
long-long
unsigned-short
unsigned-int
unsigned-long
unsigned-long-long
int8_t
int16_t
int32_t
inst64_t
uint8_t
uint16_t
uint32_t
uint64_t
float
double
void*
.- Be aware that misuse of those procedures causes a fatal error such as a segmentation fault.
(import (rnrs) (ypsilon c-ffi) (ypsilon c-types)) (c-string-ref (c-void*-ref (c-main-argv))) ;=> "ypsilon"
(c-{type}-set! <location> <value>)
procedure
- Stores a C value to a bytevector or memory
<location>
is either a bytevector or a memory address.{type}
is eitherbool
char
short
int
long
long-long
int8_t
int16_t
int32_t
inst64_t
float
double
void*
.- Be aware that misuse of those procedures causes a fatal error such as a segmentation fault.
(import (rnrs) (ypsilon c-ffi) (ypsilon c-types)) (define malloc (c-function void* malloc (size_t))) (define mem (malloc 128)) (c-double-set! mem 3.14) (c-double-ref mem) ;=> 3.14
sizeof:{type}
constant
- Constant defined to a byte size of correspondent C data types
{type}
is eitherbool
short
int
long
long-long
size_t
void*
.
sizeof:bool ;=> 1
alignof:{type}
constant
- Constant defined to an alignment size of correspondent C data types
{type}
is eitherbool
short
int
long
long-long
size_t
int8_t
int16_t
int32_t
int64_t
void*
float
double
.
alignof:short ;=> 2