Avoid copy when using data for Ptr{T}

Hi,
I call a fortran code which calls Julia trough a @cfunction using pointers (Ptr{T}), and I want to
avoid copying data from Fortran in Julia such as in the following code

using Libdl:dlopen, dlsym
using Test

function getff(n, fj)
  function proxy!(n::Cint,x::Ptr{Float64},f::Ptr{Float64})
       xv = zeros(n)
       for i=1:n           # <-I WANT TO AVOID THAT COPY
        xv[i] = unsafe_load(x, i)
       end
       fv = fj(xv)
       unsafe_store!(f,fv)
    nothing
  end
  return proxy!
end 

io = open("dummy.f", "w")
prgm="""
           subroutine apply_f(ff,n,x0,f0)
           integer*4 n
           real*8 x0(n)
           external ff                
           call ff(n, x0, f0)
           end subroutine   
     """
write(io,prgm)
close(io)
run(`gfortran -o dummy.so -shared dummy.f`)
n = 2
f(x) = x[1]^2 + x[2]^2
ff = @cfunction($(getff(n, f)), Cvoid, (Ref{Cint}, Ptr{Float64}, Ptr{Float64} ))
test_call = dlopen("./dummy.so")
test_ptr = dlsym(test_call, :apply_f_)
x0 = [1., 2.]
f0 = [1.]
ccall(test_ptr, Cvoid, (Ptr{Cvoid}, Ref{Cint}, Ptr{Float64}, Ptr{Float64}), ff, n, x0, f0)
@test f0[1] ≈ f(x0) atol=1e-30
run(`rm dummy.so dummy.f`)

The idea is to wrap directly a Vector{Float64} on my Ptr{Float64}, but I do not know how to do that

unsafe_wrap

1 Like

Hi Steven,
thanks effectively xv = unsafe_wrap(Array, x, n) do the job :+1:. The documentation is not very clear because it documentates only the case with the first argument equals to Array . Searching for examples in the sources of Julia gave me uses cases. Bests

There are other methods that take String or Memory as the first argument; it would be good to document those if someone wants to submit a PR.

I could try to do it even if I am not english native speaker and I never used these two other options . At least, I’ll have a look for other examples in Julia’s source tree

1 Like