# Can i write a fortran library and call it from F#

**URL:** <https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550>\
**Category:** Uncategorized\
**Created:** [February 25, 2024, 12:10pm UTC](https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550 "2024-02-25T12:10:26Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![devosalain](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/devosalain/32/1186_2.png) [@devosalain](https://forums.fsharp.org/u/devosalain)\
**Post date:** [February 25, 2024, 12:10pm UTC](https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550/1 "2024-02-25T12:10:26Z")

</div>

Can i write a fortran library and call it from F# ?

---

<div class="post-metadata">

**Author:** ![murphy](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/murphy/32/1373_2.png) [@murphy](https://forums.fsharp.org/u/murphy)\
**Post date:** [February 26, 2024, 1:16am UTC](https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550/2 "2024-02-26T01:16:20Z")

</div>

That is certainly possible with P/Invoke as for almost any other natively compiled language, although FORTRAN calling conventions make it slightly more painful than, for example, an interface to C.

Consider the following silly little FORTRAN 90 function:

```auto
FUNCTION foobar(x, y)
    !GCC$ ATTRIBUTES CDECL :: foobar
    REAL, INTENT (IN) :: x, y
    REAL :: foobar
    foobar = x * y + x / y
END

```

Let’s say you translate this into a Unix shared library with `gfortran -O2 -Wall -fPIC -fdefault-real-8 -fno-underscoring foobar.f95 -shared -o libfoobar.so`.

You can then write an F# module importing the function through P/Invoke:

```auto
module FromFortran =
    open System.Runtime.InteropServices

    [<DllImport("foobar", CallingConvention = CallingConvention.Cdecl)>]
    extern float foobar([<In>] float& x, [<In>] float& y)

```

Note that even though the input arguments were annotated with `INTENT (IN)` in FORTRAN, the compiler will pass them by reference, so we have to replicate that kind of calling convention on the .NET side. Also note that we had to pass special flags to the compiler to align the default type size between FORTRAN’s `REAL` and F#'s `float`, and to avoid decorating the exported names with additional underscores as compared to C language conventions (otherwise the `DllImport` attribute would likely need another argument like `EntryPoint = "foobar_"`)

A call to the function would look something like this:

```auto
let mutable x = 3.0
let mutable y = 2.0

FromFortran.foobar(&x, &y)
|> printfn "foobar(%g, %g) = %g" x y

```

Since F# favours immutability and FORTRAN insists on passing everything by (mutable) reference, there is some friction here that you would probably want to resolve with another abstraction layer over your FORTRAN library on the F# side for a real world project.

Depending on the concrete scenario it might also be an option to compile FORTRAN code to .NET IL instead of native code. [SilverFrost FORTRAN](https://www.silverfrost.com/14/ftn95/ftn95_fortran_95_for_microsoft_dotnet_features.aspx) comes to mind here, yet the calling convention issues are not much better in this case.

Let’s say you translate the above FORTRAN code into a .NET assembly with `ftn95 foobar.f95 /clr /clr_ver 4 /optimise /dreal /link foobar.dll`, then the F# code to call into it would look like this:

```auto
#nowarn "9"
#r "foobar.dll"

let x = [|3.0|]
let y = [|2.0|]
let foobar =
    use x = fixed x
    use y = fixed y
    foobar.FOOBAR(x, y)

printfn "foobar(%g, %g) = %g" x[0] y[0] foobar

```

---

<div class="post-metadata">

**Author:** ![devosalain](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/devosalain/32/1186_2.png) [@devosalain](https://forums.fsharp.org/u/devosalain)\
**Post date:** [March 1, 2024, 1:11pm UTC](https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550/3 "2024-03-01T13:11:17Z")

</div>

This is my current code.  
Fortran,  
lib.f90

```auto

module lib
contains
    subroutine print_int(i)
        implicit none
        integer, intent (in) :: i
        print *, i
    end subroutine print_int

    integer function square(i) bind(C)
        implicit none
        integer,intent(in)::i
        square=i*i
    end function square
end module lib

```

lfortran -c -Wall -fPIC lib.f90

F# code:  
Program.fs

```auto
module test =
    open System.Runtime.InteropServices
    [<DllImport("lib.o", CallingConvention=CallingConvention.Cdecl)>]
    extern int square(int)
    let _ =
        printfn "Hello from F#"
        printfn "%d" (square 5)

```

Error :

```auto
dotnet run
Hello from F#
Unhandled exception. System.DllNotFoundException: Unable to load shared library 'lib.o' or one of its dependencies. In order to help diagnose loading problems, consider using a tool like strace. If you're using glibc, consider setting the LD_DEBUG environment variable: 

```

Even if i have in the current working directory of the dotnet project a softlink to lib.o

PS : on FreeBSD i cannot build “-shared”.

So i probably must say to dotnet look into the current directory for softlinks to lib.o

---

<div class="post-metadata">

**Author:** ![murphy](https://yyz2.discourse-cdn.com/flex030/user_avatar/forums.fsharp.org/murphy/32/1373_2.png) [@murphy](https://forums.fsharp.org/u/murphy)\
**Post date:** [March 1, 2024, 4:45pm UTC](https://forums.fsharp.org/t/can-i-write-a-fortran-library-and-call-it-from-f/3550/4 "2024-03-01T16:45:50Z")

</div>

Hmm, the `BIND (C)` attribute takes care of the underscores in the symbol naming convention, but not with the fact that FORTRAN wants to pass things by reference 😠 However, I figured out that the `VALUE` attribute helps here, and that modern compilers provide an intrinsic `ISO_C_BINDING` module with constants for the right type kinds:

```auto
FUNCTION foobar(x, y) BIND (C)
    USE ISO_C_BINDING
    IMPLICIT NONE
    !GCC$ ATTRIBUTES CDECL :: foobar
    REAL (C_DOUBLE), VALUE :: x, y
    REAL (C_DOUBLE) :: foobar
    foobar = x * y + x / y
END

```

Combined with this F# code:

```auto
module F =
    open System.Runtime.InteropServices

    [<DllImport("foobar", CallingConvention = CallingConvention.Cdecl)>]
    extern float foobar(float x, float y)

let x = 3.0
let y = 2.0

F.foobar(x, y)
|> printfn "foobar(%g, %g) => %g" x y

```

I can successfully run the code using:

```auto
gfortran -O2 -Wall -fPIC foobar.f95 -shared -o libfoobar.so
LD_LIBRARY_PATH="$PWD" dotnet fsi foobar.fsx

```

Note that I _have_ to compile the code into a shared object. Obviously, the .NET runtime cannot just load some static object with incomplete linkage into a process.

If the creation of shared libraries really isn’t an option, it may be possible to use the [Native AOT](https://learn.microsoft.com/en-us/dotnet/core/deploying/native-aot/interop) machinery to compile your entire .NET code into machine code and link both the full .NET runtime and any externally provided objects you like into one executable.
