Search code examples
c++visual-studioqtfortraninterop

Passing complex data structures between Fortran and C++


Background: I am tasked with a work project of creating interoperability between an existing large Fortran code basis and a modern C++ GUI using Qt. I am using Qt Creator 6.0.2 based on Qt 6.2.2 (MSVC 2019, 64 bit) and VS 2019 Pro with the Intel Fortran Compiler.

I have been able to successfully pass basic data types and simple structures/UDT between Fortran and Qt, but as I try to get into more complex data structures I am running into lots of issues and confusion. I've spent many hours googling this, but everything I can find is limited to basic data type examples.

So my question ultimately is if you have a data structure in Fortran that looks like this:

module example
   type top_struct
      type(sub_struct), allocatable :: sStruct(:)
      complex         , allocatable :: complex1(:)
      real            , allocatable :: real1(:, :)
      integer         , allocatable :: ints1(:, :)
      character       , allocatable :: label1(:)
   end type top_struct
   
   type sub_struct
      complex         , allocatable :: complex2(:)
      real            , allocatable :: real2(:, :)
      integer         , allocatable :: ints2(:, :)
      character       , allocatable :: label2(:)
   end type sub_struct
end module

how would you implement code in both C++ and Fortran that would allow you to pass this structure back and forth between them?

I found other questions that discussed using pointers to workaround there not being a direct correlation between allocatable in Fortran and something like std::vector in C++, but they didn't give any examples as to how to handle this if the data is inside of a structure/UDT.

Any help would be greatly appreciated!


Solution

  • Unless your structure is bind(C), no exact correspondence between C(++) and Fortran can be guaranteed. The compilers can choose to use different paddings or similar. But you cannot make a bind(C) structure with allocatable components. All that is left are hacks.

    As a workaround you could make a proxy structure with type(c_ptr) pointers that point to those allocatable arrays and pass to C(++) this proxy.