Skip to content

Commit

Permalink
Allow passing NTuple{N,T} as Ref{T}/Ptr{T} to ccall
Browse files Browse the repository at this point in the history
This makes it convenient when working with APIs that use small arrays.

Based on discussion in https://discourse.julialang.org/t/ccall-with-pointer-argument-to-array-of-custom-type-via-an-ntuple-of-immutables/1048/2
  • Loading branch information
simonbyrne committed Dec 26, 2019
1 parent ce498d6 commit b1263e5
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 0 deletions.
11 changes: 11 additions & 0 deletions base/refpointer.jl
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,17 @@ cconvert(::Type{Ref{P}}, a::Array{<:Ptr}) where {P<:Ptr} = a
cconvert(::Type{Ptr{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)
cconvert(::Type{Ref{P}}, a::Array) where {P<:Union{Ptr,Cwstring,Cstring}} = Ref{P}(a)


cconvert(::Type{Ref{T}}, t::NTuple{N,T}) where {N,T} = Ref{NTuple{N,T}}(t)
cconvert(::Type{Ptr{T}}, t::NTuple{N,T}) where {N,T} = Ref{NTuple{N,T}}(t)
cconvert(::Type{Ref{T}}, r::Ref{NTuple{N,T}}) where {N,T} = r
unsafe_convert(::Type{Ref{T}}, r::Ref{NTuple{N,T}}) where {N,T} =
convert(Ptr{T}, unsafe_convert(Ptr{NTuple{N,T}}, r))
unsafe_convert(::Type{Ptr{T}}, r::Ref{NTuple{N,T}}) where {N,T} =
convert(Ptr{T}, unsafe_convert(Ptr{NTuple{N,T}}, r))
unsafe_convert(::Type{Ptr{T}}, r::Ptr{NTuple{N,T}}) where {N,T} =
convert(Ptr{T}, r)

###

getindex(b::RefArray) = b.x[b.i]
Expand Down
21 changes: 21 additions & 0 deletions test/ccall.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1546,3 +1546,24 @@ ERROR: could not load library "does_not_exist"
does_not_exist.so: cannot open shared object file: No such file or directory
""")
@test !isfile(o_file)

# pass NTuple{N,T} as Ptr{T}/Ref{T}
let
dest = Ref((0,0,0))

src = Ref((1,2,3))
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Int}, Ptr{Int}, Csize_t), dest, src, 3*sizeof(Int))
@test dest[] == (1,2,3)

src = Ref((4,5,6))
ccall(:memcpy, Ptr{Cvoid}, (Ref{Int}, Ref{Int}, Csize_t), dest, src, 3*sizeof(Int))
@test dest[] == (4,5,6)

src = (7,8,9)
ccall(:memcpy, Ptr{Cvoid}, (Ptr{Int}, Ptr{Int}, Csize_t), dest, src, 3*sizeof(Int))
@test dest[] == (7,8,9)

src = (10,11,12)
ccall(:memcpy, Ptr{Cvoid}, (Ref{Int}, Ref{Int}, Csize_t), dest, src, 3*sizeof(Int))
@test dest[] == (10,11,12)
end

0 comments on commit b1263e5

Please sign in to comment.