No. Even if you corrected the code to arr = Ptr{Float64}(0)
, it won’t work because arr
is bound to an immutable object.
The problem is that passing this arr
for a Ref{Ptr{Float64}}
argument doesn’t pass a “pointer to arr
” — it’s not analogous to passing &arr
in C. What it does is to construct a new Ref(arr)
mutable object that wraps a copy of arr
’s value, and the contents of this new object are what get mutated inside the Fortran subroutine. However, you can’t access the mutated contents after the ccall
returns, because you didn’t give a name to this new Ref
object.
To give a simpler example, suppose you have a C function:
void getRandomNumber(int *x) {
*x = 4; // chosen by fair dice roll, guaranteed to be random
}
Suppose we call it in Julia by:
ccall(:getRandomNumber, Cvoid, (Ref{Cint},), 17)
How would you get the value 4
out? Clearly, you can’t (and don’t want) to “change the value of 17
” … 17
is an immutable value. What the ccall
does is to construct a Ref{Cint}(17)
object, which gets passed as a pointer to the C function, and the contents of that object get mutated.
But if you do
x = 17
ccall(:getRandomNumber, Cvoid, (Ref{Cint},), x)
it is exactly equivalent to passing 17
directly. The function call cannot change the value of x
, for the same reason that
y = x
y = 4
does not change the value of x
to 4
. See also the manual section on assignment vs. mutation.
Instead, you do:
xref = Ref{Cint}(17)
ccall(:getRandomNumber, Cvoid, (Ref{Cint},), xref)
after which xref[]
(the contents of the Ref
object) should be 4
.
This is analogous in C to:
int xref[] = {17}; // a mutable container for 17, analogous to Ref{Cint}(17)
getRandomNumber(xref);
after which *xref
should be 4
.