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] = 9
This 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 thei
th element, assuming the pointer points to an array.p.name
is anUnsafePtr
to thename
field ofp[]
. For tuples,p._n
refers to then
th field.p+i
is anUnsafePtr
to thei
th next element.(p+i-1)[]
andp[i]
are equivalent.p-q
is the number of elements betweenp
andq
, 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 thei
th element for eachi ∈ idxs
.String(p, [length])
convertsp
to 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]