Help calling fortran subroutines using ccall

Hi, I’m trying to replicate SWxTREC/pymsis in Julia, specifically the fortran call of the following subroutines (pymsis/src/wrappers at main · SWxTREC/pymsis · GitHub). To do so, I have created the following fortran script, based on the msis2.F90 script in the above link. I noticed that there is also msis21.pyf that calls the same subroutines while implementing an interface. This is the code I have written/adapted from the link:

module julia_wrapper
contains
 subroutine juliainitswitch(switch_legacy, parmpath) 
      use msis_init, only: msisinit
  
      implicit none
  
      real(4), intent(in), optional             :: switch_legacy(1:25)      !Legacy switch array
      character(len=*), intent(in), optional    :: parmpath                 !Path to parameter file
  
      call msisinit(switch_legacy=switch_legacy, parmpath=parmpath)
  
      return
  end subroutine juliainitswitch
  
  subroutine juliamsiscalc(n, day, utsec, lon, lat, z, sflux, sfluxavg, ap, output)
      use msis_calc, only: msiscalc
      use msis_constants, only: rp
  
      implicit none
  
      integer, intent(in)        :: n
      real(kind=rp), intent(in)  :: day(n)
      real(kind=rp), intent(in)  :: utsec(n)
      real(kind=rp), intent(in)  :: lon(n)
      real(kind=rp), intent(in)  :: lat(n)
      real(kind=rp), intent(in)  :: z(n)
      real(kind=rp), intent(in)  :: sflux(n)
      real(kind=rp), intent(in)  :: sfluxavg(n)
      real(kind=rp), intent(in)  :: ap(n, 1:7)
      real(kind=rp), intent(out) :: output(n, 1:11)
  
      integer :: i
  
      do i=1, n
          call msiscalc(day(i), utsec(i), z(i), lat(i), lon(i), sfluxavg(i), &
                      sflux(i), ap(i, :), output(i, 11), output(i, 1:10))
      enddo
  
  end subroutine juliamsiscalc
end module julia_wrapper

and I use ccall in this way:

options = ones(25)
options = convert(Vector{Float32}, options)
msis_path = "./nrlmsis2.1/"
ccall((:__julia_wrapper_MOD_juliainitswitch,"./nrlmsis2.1/julia_wrapper.dylib"),
    Cvoid,
    (Ptr{Float32}, Ptr{UInt8}, Ref{Csize_t}), 
    options, msis_path, sizeof(msis_path))

Here you can find the link to the tar.gz file https://map.nrl.navy.mil/map/pub/nrl/NRLMSIS/NRLMSIS2.1/. After unzip it, I have created the julia_wrapper.F90 file (containing the code above), and created the .dylib (on a macbook M1 pro and gfortran):
gfortran -o julia_wrapper.dylib -shared -fPIC msis_constants.F90 msis_utils.F90 msis_init.F90 msis_gfn.F90 msis_tfn.F90 msis_dfn.F90 msis_calc.F90 msis_gtd8d.F90 julia_wrapper.F90

When I use ccall on Visual Studio, the code never stops, it just runs for like minutes without giving any output or letting me stop it. My question is, what am I doing wrong? How should I edit julia_wrapper.F90? I found out online that “iso_c_binding” can be maybe helpful, but I have no knowledge of fortran.

Any help would be really appreciated! Thanks!

1 Like