# Fortran-Julia interface for program containing non-c-interoperable derived type

**URL:** <https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815>\
**Category:** General Usage\
**Tags:** question, ccall, fortran\
**Created:** [November 27, 2023, 5:11pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815 "2023-11-27T17:11:04Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![tmph](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@tmph](https://discourse.julialang.org/u/tmph)\
**Post date:** [November 27, 2023, 5:11pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/1 "2023-11-27T17:11:04Z")

</div>

I’m still new to Julia (and this discourse), but couldn’t find the answer to this question anywhere.

I have a large Fortran legacy code base which I’m trying to interface with a high-level language. I got something kind of working with Cython, and a MWE for that can be found on StackOverflow here: [Fortran C interface for program containing non-c-interoperable derived type](https://stackoverflow.com/questions/77202555/fortran-c-interface-for-program-containing-non-c-interoperable-derived-type).

I’ve read/heard that interface C/Fortran to Julia is really simple, so I want to do the same sort of thing in Julia, I guess with `ccall`, though I’m getting quite lost.

Here is some Fortran code,

```fortran
module somemodule
    use, intrinsic :: iso_c_binding
    implicit none

    type :: sometype
       integer(c_int), allocatable :: a(:)
       integer(c_int) :: b
    end type

    type, bind(c) :: someothertype
       integer(c_int) :: c
    end type someothertype

 contains

    ! example routine that processes the content of the type
    subroutine sometype_x2_f(x)
       type(sometype), intent(inout) :: x

       x%a = 2 * x%a
    end subroutine

    subroutine sometype_init_f(x, n)
        type(sometype), intent(inout) :: x
        integer(c_int), intent(in) :: n
        integer(c_int) :: i
        x%a = [(i, i=0, n)]
    end subroutine sometype_init_f

    integer(c_int) function sometype_sum_f(x) result(res)
        type(sometype), intent(inout) :: x
        res = sum(x%a)
    end function sometype_sum_f

    subroutine someothertype_x2_f(x)
       type(someothertype), intent(inout) :: x

       x%c = 2 * x%c
    end subroutine

 end module

```

which I can compile into a shared .so library and then call into a duplicate of someothertype in Julia:

```julia
mutable struct SomeOtherType
    c::Cint
end
x = SomeOtherType(2)

println("x = $x (before)")
ccall((:__somemodule_MOD_someothertype_x2_f, "./libsometype_module.so"), Cvoid, (Ref{SomeOtherType},), x)
println("x = $x (after)")

```

which gives the expected

```julia
x = SomeOtherType(2) (before)
x = SomeOtherType(4) (after)

```

(hooray)

In my code, `sometype%a` might be very large, so I would not want it duplicated in Julia (at least until I manage to rewrite the Fortran into Julia ;)). is there a way to keep the `x%a` variable opaque to Julia (or otherwise avoid storing it twice, as I guess is done for `someothertype%c`, e.g. with pointers) while still getting access to `x%b`, and running (Fortran) functions that use/modify `x%a`, such as `sometype_x2_f`? Do I still need all the boilerplate code for wrapping these functions as I did in Cython (`somemodule_wrap` in the SO thread and getter/setters for other variables e.g. `x%b`)?

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 27, 2023, 5:27pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/2 "2023-11-27T17:27:51Z")

</div>

There is a `Ptr{Nothing}` Julia type that is analogous to a `void*` in C. You can use `unsafe_load` and `unsafe_store!` to read or write to the pointer. There is also `unsafe_wrap` which allows you to wrap a Julia `Array` around a pointer.

---

<div class="post-metadata">

**Author:** ![tmph](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@tmph](https://discourse.julialang.org/u/tmph)\
**Post date:** [November 28, 2023, 7:38am UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/3 "2023-11-28T07:38:02Z")

</div>

Thanks for the reply, do I understand correctly that these would basically require the same sort of solution as Cython? i.e. I would need to make setters and getters for all members (which I want to access) in the Fortran derived type and write C-interoperable wrappers? I guess it looks like boilerplate code then is essentially unavoidable here.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 28, 2023, 3:24pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/4 "2023-11-28T15:24:50Z")

</div>

Thr Cython solution should work here as well.

I think we can do better by creating a struct with a compatible memory layout as your Fortan types.

What would the C equivalent of your Fortran types be?

Just to make sure, here is the Julia manual section on this:

[https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/](https://docs.julialang.org/en/v1/manual/calling-c-and-fortran-code/)

---

<div class="post-metadata">

**Author:** ![tmph](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@tmph](https://discourse.julialang.org/u/tmph)\
**Post date:** [November 28, 2023, 4:00pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/5 "2023-11-28T16:00:10Z")

</div>

Yes, it would be nice to do better than Cython, specifically if we can have a little less boilerplate code (though maybe this is not possible).

Because of the allocatable array, my `sometype` type has no C equivalent (in reality the type is a fair bit more complicated, but I’m using this as a stand-in). I’m happy not being able to access it directly (as would be done with C/Cython), but I’d like to be able to call Fortran functions involving it (which I guess is where the pointers come in) and manipulate the other members of the type (in my example, `sometype%b`).

I’ve seen the link but haven’t found a solution to my problem on there. My impression, though, is that I need to basically follow the solution in the StackOverflow thread (which involves a lot of wrapper functions in Fortran), then use `ccall` with pointers.

---

<div class="post-metadata">

**Author:** ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)\
**Post date:** [November 28, 2023, 4:31pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/6 "2023-11-28T16:31:51Z")

</div>

I think you are correct that there is no C equivalent to `sometype`. However, I think you can can return pointers to each of the elements of `sometype`. That is we can obtain pointers to `a` and `b`.

What I’m wondering is what about the large datatype that `a` points to? Can we map that to C and thus Julia?

Julia is basically has its Cython equivalent builtin. We can operate with C really well. Julia operates with Fortran via a C interface, so essentially have those same issues. However, Julia structs are designed to be C compatible.

My Fortran knowledge is limited. Perhaps @certik might be helpful here.

I also see an extended discussion on this matter on the Frotran forums:

> **[Allocate interoperability and C descriptors](https://fortran-lang.discourse.group/t/allocate-interoperability-and-c-descriptors/5088)**
>
> Let’s say one have a Fortran library with some routines that have allocatable arrays as dummy arguments, and one want to pass data in these arguments from C. Constraints: the library must not be modified, and the data must not be duplicated. It...

---

<div class="post-metadata">

**Author:** ![tmph](https://avatars.discourse-cdn.com/v4/letter/t/e36b37/32.png) [@tmph](https://discourse.julialang.org/u/tmph)\
**Post date:** [November 28, 2023, 4:59pm UTC](https://discourse.julialang.org/t/fortran-julia-interface-for-program-containing-non-c-interoperable-derived-type/106815/7 "2023-11-28T16:59:45Z")

</div>

By “the large datatype that `a` pointers to” do you mean what the actual datatype is? The actual data type is an array that’s shared across machines (i.e. it has a bunch of MPI information baked in). It’s also one of many generated with fypp. I’m sure with enough effort it’s possible to convert, but (1) I don’t really understand the structure and the author (no longer in the group) did a good job providing an understandable interface, and (2) these are very large: by my understanding by interoperating with Julia this way we are essentially copying over the entire data structure to Julia to operate further. This would be very expensive in terms of memory. I’d rather not open that can of worms and just never directly access it in Julia, if possible. I chose `a` to be `allocatable` in this MWE specifically because I know it’s not C-interoperable so it works as a proxy.

> [@mkitti](#):
>
> That is we can obtain pointers to `a` and `b`.

Is this the “getters and setters” I mentioned? Not a big deal, just annoying boilerplate code (maybe less so with metaprogramming tools). One would have to provide `get_b` and `set_b` Fortran functions, basically, or can you somehow avoid that? Maybe it is avoidable because Julia has pointers (unlike Python). Can you explain how you would access (say) `b` without redefining the structure in Julia?

> [@mkitti](#):
>
> I also see an extended discussion on this matter on the Frotran forums:

Interesting tidbit: the person asking the question on the discourse link you sent appears to be the same one who answered my StackOverflow question. I’ll have to take a look; you are right that there seems to be some overlap with that question and mine. Thank you!
