CStructures.CStruct
— TypeCStruct{T}(p::Ptr)
Given a C-type pointer p
to a C-struct and the equivalent Julia struct with the same memory layout T
, provide read and write access to the fields. T
must be a bits type.
Example: struct T <: Layout a::Cint b::Cdouble end
a = Vector{UInt8}(undef, 100) p = pointer(a) # usually the data are coming from C cs = CStruct{T}(p)
cs.a = 1234 cs.b = 3.5
CStructures.CVector
— TypeCVector
Abstract vector type for julia objects used to access elements of C-vectors, which are based by plain C memory. Memory layout is described by Layout
structs.
CStructures.LFixedVector
— TypeLFixedVector{T,N}
Denote a fixed size vector with element type T
and size N
.
CStructures.LVarVector
— TypeLVarVector{T,F}
Denote a variable length vector with element type T
in a template. F
is a function, which calculates the length of the vector, given the accessor object containing the vector.
Example: struct A <: Layout len::Int vec::NVarVector{Float64, (x) -> x.len} end
CStructures.Layout
— TypeLayout
All structs used to describe the memory layout (of a C-data structure) need to be subtypes of this. Some controlling objects used in such templates to describe vectors and pointers have also this type. A Layout
structure and a memory pointer are needed to construct an CAccessor
object.
Base.pointer
— Methodpointer(::Union{CStruct,CVector})
length(::CVector)
get the internal fields of accessors
CStructures.Cserialize
— MethodCserialize(::Type{T}, source::Any)
Convert the julia object source
into a byte vector to be used in C. The process is controlled by the layout type recursively.
The resulting vector contains only data described in T
. The field, vector element or bit data required by T
are taken from source
if available in a corresponding part. Other data are filled with 0-bytes.
If T
is a structure, corresponding fields in source are by the same name. If T
is a vector, corresponding elements in source are by the same index. If T
is a Ptr{S}
, the space for a pointer is reserved and filled with the offset integer (of same size), while the S
object is appended at the end of the serialization stream.
Finally all offset integers are replaced by actual pointers.
CStructures.ensure!
— Methodensure!(buf::Vector, off, size)
Ensure that the size of buf
is at least off + size
by maybe resizing buf
. Added space is filled with zero bytes.
CStructures.get_from_pointer
— Methodget_from_pointer(::Ptr{T})
For bits types simply load value, convert to Julia accessor if required. For struct types, create CStruct accessor. For vector types, create CVector accessor.
CStructures.is_layout_fixed
— Functionis_template_fixed(type)
Has the layout described by type
a fixed size.
CStructures.is_layout_variable
— Functionis_template_variable(type)
Has the layout described by type
a variable size (for example variable sized vector in last field of a struct)?
CStructures.pointer_for_field
— Methodpointer_for_field(cs::CStruct{T}, fieldname) where T
For cs
return pointer to member field fieldname
. The pointer has type Ptr{fieldtype(T, i)}
with i
the number of the field within struct type T
.
CStructures.pointer_from_vector_obs
— Methodp = pointer(a::Vector{T})::Ptr{T}
return pointer to a[1]
. The existence of the resulting Ptr will not protect the object from garbage collection, so you must ensure that the object remains referenced for the whole time that the Ptr will be used. The condition a[i] === unsafe_load(p, i)
is usually true. Given p
it is possible to access arbitrary bits data by byte offset and type S
using unsafe_load(Ptr{S}(p + offset))
.
This function is mainly used to simulate a C memory in the data area of vector a
.
CStructures.pushall!
— Methodpushall!(relocs::Vector{Int}, ctx::Vector{Tuple}, offset, Type, value}
push! the offset
to relocs
and the tuple (offset, Type, value)
in ctx
. The relocs
are finally used to replace offset values by pointers. The ctx
is used push back processing for later serializing.
CStructures.relocate!
— Methodrelocate!(buffer::Vector, offsets)
In vector buffer
, at the byte offsets stored in offsets
, offset values (into buffer) are stored as Int
values. The are replaced by Ptr
values into the data area of buffer
.
It is essential, that the data area is not changed after this process, that means no resize!
, push!
, etc. are allowed after this final fix of pointer values to be used in C-calls.
CStructures.set_at_pointer!
— Methodset_at_pointer(:Ptr, value)
Convert to C primitive or composed object. Store bytes at memory position.