# Mutating fields of an array of structs originating from C

**URL:** <https://discourse.julialang.org/t/mutating-fields-of-an-array-of-structs-originating-from-c/69375>\
**Category:** General Usage\
**Tags:** question\
**Created:** [October 7, 2021, 2:36pm UTC](https://discourse.julialang.org/t/mutating-fields-of-an-array-of-structs-originating-from-c/69375 "2021-10-07T14:36:43Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![KajWiik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kajwiik/32/199_2.png) [@KajWiik](https://discourse.julialang.org/u/KajWiik)\
**Post date:** [October 7, 2021, 2:36pm UTC](https://discourse.julialang.org/t/mutating-fields-of-an-array-of-structs-originating-from-c/69375/1 "2021-10-07T14:36:43Z")

</div>

I am calling a C library that returns a pointer to an array of  
structs. My goal is to make views that are arrays of the field  
values, much like [StructArrays](https://github.com/JuliaArrays/StructArrays.jl) does. However, StructArrays does not let  
to mutate the underlying structure but generates a copy. The same  
seems to apply to [StructViews](https://github.com/Vitaliy-Yakovchuk/StructViews.jl).

Something like this in pseudocode (working MWE is a bit hard to generate):

```julia
struct Ex
    a::Float64
    b::Int64
end

exptr = ccall((:new_ex, libex), Ptr{Ex}, (Cstring, Cdouble), filename, par)

# exptr:
# Ptr{Ex} @0x0000000002f8de20

ex = unsafe_wrap(Array{Ex}, exptr, 2) 
2-element Vector{Ex}:
 Ex(1.0, 1)
 Ex(2.0, 2)

sa_ex = StructArrayLike(ex);

sa_ex.a
2-element Vector{Float64}:
 1.0
 2.0

sa_ex.a[2] = 100.0

ex = unsafe_wrap(Array{Ex}, exptr, 2) 
2-element Vector{Ex}:
 Ex(1.0, 1)
 Ex(100.0, 2)

# The mutated structure could then be passed to a C function: 
retval = ccall((:dosomething, libex), Cint, (Ptr{Ex}, Cint), exptr, k)

```

Has this been implemented in any package? Could the arrays e.g. be ‘stitched up’ from field value pointers? There are not so many arrays so a less general solution would be acceptable.

---

<div class="post-metadata">

**Author:** ![KajWiik](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/kajwiik/32/199_2.png) [@KajWiik](https://discourse.julialang.org/u/KajWiik)\
**Post date:** [October 8, 2021, 12:56pm UTC](https://discourse.julialang.org/t/mutating-fields-of-an-array-of-structs-originating-from-c/69375/2 "2021-10-08T12:56:42Z")

</div>

It seems that this is not possible, at least with Clang.jl.

Another possibility to work with the library would be to generate and allocate a new structure and call the library with a pointer to that. But if I have understood correctly, it is possible to get pointers only to arrays and not to other objects, right?

Is the only possibility then to write a C helper function that returns pointer to a simple array? CBinding.jl?

---

<div class="post-metadata">

**Author:** ![krrutkow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/krrutkow/32/9138_2.png) [@krrutkow](https://discourse.julialang.org/u/krrutkow)\
**Post date:** [October 8, 2021, 3:12pm UTC](https://discourse.julialang.org/t/mutating-fields-of-an-array-of-structs-originating-from-c/69375/3 "2021-10-08T15:12:07Z")

</div>

I am not exactly sure what you are wanting to do, but StructViews works for your example code. An important detail is if you are using `unsafe_wrap` multiple times on the same pointer, you should use `unsafe_wrap(..., own = false)`.

```julia
julia> using StructViews

julia> struct Ex
           a::Float64
           b::Int64
       end

julia> exptr = reinterpret(Ptr{Ex}, Libc.malloc(1000))
Ptr{Ex} @0x0000000000fe5360

julia> ex = unsafe_wrap(Array{Ex}, exptr, 2, own = false)
2-element Vector{Ex}:
 Ex(6.811895e-317, 0)
 Ex(0.0, 0)

julia> sa_ex = StructView(ex);

julia> sa_ex.a
2-element FieldView{Float64, :a, 1, IndexLinear(), :immutable}:
 6.811895e-317
 0.0

julia> sa_ex.a[2] = 100.0
100.0

julia> ex = unsafe_wrap(Array{Ex}, exptr, 2, own = false)
2-element Vector{Ex}:
 Ex(6.811895e-317, 0)
 Ex(100.0, 0)

```
