I have written a Fortran subroutine to compute the size of an array and I want to get the result directly in R. However, I do not get the expected result.
First I build the size95.f95
file
subroutine fsize(x, n)
double precision, intent(in):: x(:)
integer, intent(out) :: n
n = size(x)
end subroutine fsize
Then I compile it at CMD of Windows with
R CMD SHLIB size95.f95
Although, after I load and test it in R for a 10-element vector, I get a length of 1 instead of 10.
x <- 1:10
dyn.load("size95.dll")
dotCall64::.C64("fsize",
SIGNATURE = c("double", "integer"),
INTENT = c("r", "w"),
x=x, n=dotCall64::integer_dc(1))
# $x
# NULL
#
# $n
# [1] 1
The desired output should be
# $x
# NULL
#
# $n
# [1] 10
R itself does not understand Fortran assumed shape arrays (such as x
of fsize
). There's a lot of work required to use an assumed shape argument in R and even dotCall64
does not do that for you.
Recall that Fortran 77 didn't have assumed shape arrays. Recall also that in more recent Fortran a Fortran compiler must be told ("explicit interface") when a procedure argument is assumed shape.
The Fortran compiler must be told because assumed shape arguments are (generally) implemented using dope vectors.1 That is, what is passed to the procedure is not the data (like 1:10
) alone, but the data and additional stuff.
C interoperability with Fortran does allow use of assumed shape arrays, and it's a lot of work. You'll be able to do something similar with R. However, one of the things you need to know to be able to set up the dope vector is the size of the input array: lots of work for no return in this case.
For now, stick to using scalars or explicit shape arrays.
1 Linked in this answer are details of Intel's array descriptor. GCC has similar.