Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/cjdoris/unsafepointers.jl
Convenient (but unsafe) pointer access
https://github.com/cjdoris/unsafepointers.jl
Last synced: 24 days ago
JSON representation
Convenient (but unsafe) pointer access
- Host: GitHub
- URL: https://github.com/cjdoris/unsafepointers.jl
- Owner: cjdoris
- License: mit
- Created: 2020-07-20T14:29:27.000Z (over 4 years ago)
- Default Branch: master
- Last Pushed: 2024-09-06T09:10:11.000Z (2 months ago)
- Last Synced: 2024-10-10T17:47:22.813Z (26 days ago)
- Language: Julia
- Size: 52.7 KB
- Stars: 5
- Watchers: 3
- Forks: 4
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
README
# UnsafePointers.jl
[![Project Status: Active – The project has reached a stable, usable state and is being actively developed.](https://www.repostatus.org/badges/latest/active.svg)](https://www.repostatus.org/#active)
[![Test Status](https://github.com/cjdoris/UnsafePointers.jl/actions/workflows/tests.yml/badge.svg)](https://github.com/cjdoris/UnsafePointers.jl/actions/workflows/tests.yml)
[![Codecov](https://codecov.io/gh/cjdoris/UnsafePointers.jl/branch/main/graph/badge.svg?token=1flP5128hZ)](https://codecov.io/gh/cjdoris/UnsafePointers.jl)Convenient (but unsafe) pointer accesses.
```julia
# 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.
## Install
```
pkg> add UnsafePointers
```## Usage
```julia
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 the `i`th element, assuming the pointer points to an array.
* `p.name` is an `UnsafePtr` to the `name` field of `p[]`. For tuples, `p._n` refers to the `n`th field.
* `p+i` is an `UnsafePtr` to the `i`th next element. `(p+i-1)[]` and `p[i]` are equivalent.
* `p-q` is the number of elements between `p` and `q`, so that `p === q+(p-q)`.
* Iteration yields `p[1]`, `p[2]`, ... forever.
* `Array(p, dims...)` is an array view of contiguous data pointed to by `p` (equivalent to `unsafe_wrap(Array, pointer(p), dims)`).
* `p[idxs]`/`view(p, idxs)` is an array/view of the `i`th element for each `i ∈ idxs`.
* `String(p, [length])` converts `p` to a string (equivalent to `unsafe_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.
## Safety
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.
## Example
Here we access and modify the individual fields of a (mutable) reference to a (immutable) named tuple.
```julia
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]
```