The following pseudo-code represents a reduced example of a library I am wrapping. The code actually works well, however I think that there are exceptional cases where it is potentially unsafe (see comments below where the convert function is defined).
It may very well be that there is nothing wrong with the code below. I welcome feedback.
# the C library has a struct of this layout
struct CstructX
w::Cint
h::Cint
p::Ptr{UInt8}
end
function Base.convert(::Type{CstructX}, A::AbstractMatrix{NTuple{4,UInt8}})
# potentially unsafe ?
CstructX(size(A)..., Base.unsafe_convert(Ptr{UInt8}, A)) # yes we want to interpret the array of NTuple{4,UInt8} as Ptr{UInt8}
end
# the C function expects a pointer to a vector of structs with the CstructX layout
function cwrapper(A::Vector{<:AbstractMatrix{NTuple{4,UInt8}}})
Aconv = unsafe_convert(Vector{CstructX}, A)
ccall((:test), Cvoid, (Cint, Ptr{Vector{CstructX}}), length(A), Aconv)
end
# pseudo code to call the cwrapper
a = rand(UInt8, 24, 24)
a = reinterpret(NTuple{4,UInt8}, A)
A = [a, a, a]
callcfunction(a)