I need to pass a struct that may contain an array of its own type to a C library. To achieve that, I use the pointer
function to obtain an address and encode that in an UInt64
field (as expected by the C library).
I’ve seen random crashes or corrupted data, so I’m guessing that I must be doing something wrong here. I wonder if it’s because the array ar
got GC’ed even though the object is still around. If that’s the case, what would be the correct way to maintain the reference or avoid GC?
Here’s the MWE to illustrate the situation:
julia> struct Bar
val::UInt64
ty::UInt8
Bar(v::Float64) = new(reinterpret(UInt64, v), 0x00)
Bar(vv::Vector{Float64}) = begin
ar = Bar.(vv)
new(reinterpret(UInt64, pointer(ar)), 0x01)
end
end
So the value of val
could either be a Float64
value or the address of an object of type Vector{Bar}
. Here’s how to construct such objects:
julia> b1 = Bar(1.0)
Bar(0x3ff0000000000000, 0x00)
julia> b2 = Bar([2.0, 3.0])
Bar(0x0000000123aea430, 0x01)
To get the array back, I could do this:
julia> p2 = reinterpret(Ptr{Bar}, b2.val)
Ptr{Bar} @0x000000012b38b700
julia> q2 = unsafe_load.(p2, 1:2)
2-element Array{Bar,1}:
Bar(0x4000000000000000, 0x00)
Bar(0x4008000000000000, 0x00)
julia> [reinterpret(Float64, x.val) for x in q2]
2-element Array{Float64,1}:
2.0
3.0