Convenient (but unsafe) pointer accesses.
# In C you do this:
p->second_field[3] = 9
# In base Julia you do this:
unsafe_store!(
unsafe_load(
unsafe_load(p) + fieldoffset(eltype(p), 2)
) + 3 * sizeof(fieldtype(eltype(p), 2)),
9
)
# Now you can do this:
q = UnsafePtr(p)
q.second_field[][4] = 9This package exports one type, UnsafePtr{T}, which behaves similarly to a regular Ptr{T} but has some convenient (but unsafe) pointer access semantics.
Useful for example for accessing or modifying data exposed by C interfaces through pointers.
pkg> add UnsafePointers
UnsafePtr{T}(r)A pointer to the contents of r which may be a Ptr, Ref, Array, String or anything with a pointer(r) method.
T specifies the element type and is optional.
It has convenient (but unsafe) semantics:
p[]dereferences the element, and can be assigned to.p[i]dereferences theith element, assuming the pointer points to an array.p.nameis anUnsafePtrto thenamefield ofp[]. For tuples,p._nrefers to thenth field.p+iis anUnsafePtrto theith next element.(p+i-1)[]andp[i]are equivalent.p-qis the number of elements betweenpandq, so thatp === q+(p-q).- Iteration yields
p[1],p[2], ... forever. Array(p, dims...)is an array view of contiguous data pointed to byp(equivalent tounsafe_wrap(Array, pointer(p), dims)).p[idxs]/view(p, idxs)is an array/view of theith element for eachi ∈ idxs.String(p, [length])convertspto a string (equivalent tounsafe_string(pointer(p), length)).
The first four operations have these C equivalents: *p, p[i-1], &(p->name) and p+i.
If the result of dereferencing is pointer-like then an UnsafePtr is returned instead (see doautowrap). Use p[!,i] or unsafe_load(p,i) to get the original value.
It is the caller's responsibility to ensure that the pointer remains valid, e.g. by ensuring that r is not garbage collected.
You will likely crash Julia if you assign to a non-bitstype value.
Here we access and modify the individual fields of a (mutable) reference to a (immutable) named tuple.
r = Ref((a=1, b=(2, 3)))
@show r[] # (a = 1, b = (2, 3))
p = UnsafePtr(r)
p.a[] = 99
p.b._2[] *= 10
@show r[] # (a = 99, b = (2, 30))
@show Array(p.a, 3) # [99, 2, 30]