A struct
declaration inside a lib
declares a C struct.
lib C # In C: # # struct TimeZone { # int minutes_west; # int dst_time; # }; struct TimeZone minutes_west : Int32 dst_time : Int32 end end
You can also specify many fields of the same type:
lib C struct TimeZone minutes_west, dst_time : Int32 end end
Recursive structs work just like you expect them to:
lib C struct LinkedListNode prev, _next : LinkedListNode* end struct LinkedList head : LinkedListNode* end end
To create an instance of a struct use new
:
tz = C::TimeZone.new
This allocates the struct on the stack.
A C struct starts with all its fields set to "zero": integers and floats start at zero, pointers start with an address of zero, etc.
To avoid this initialization you can use uninitialized
:
tz = uninitialized C::TimeZone tz.minutes_west # => some garbage value
You can set and get its properties:
tz = C::TimeZone.new tz.minutes_west = 1 tz.minutes_west # => 1
If the assigned value is not exactly the same as the property's type, to_unsafe will be tried.
You can also initialize some fields with a syntax similar to named arguments:
tz = C::TimeZone.new minutes_west: 1, dst_time: 2 tz.minutes_west # => 1 tz.dst_time # => 2
A C struct is passed by value (as a copy) to functions and methods, and also passed by value when it is returned from a method:
def change_it(tz) tz.minutes_west = 1 end tz = C::TimeZone.new change_it tz tz.minutes_west # => 0
Refer to the type grammar for the notation used in struct field types.
To the extent possible under law, the persons who contributed to this workhave waived
all copyright and related or neighboring rights to this workby associating CC0 with it.
https://crystal-lang.org/docs/syntax_and_semantics/c_bindings/struct.html