2

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!

2
  • As per Fortran 2018 standard, a C-interoperable Fortran derived-type cannot have allocatable or pointer components. The restriction allows the type to interoperate with a C structure type with the same number of components and definition order. However, Fortran 2018 does provide a standard mechanism for interoperating Fortran allocatable variables using C descriptors from iso_fortran_binding.h. A good reference on the topic is Chapter 21 of Modern Fortran Explained: Incorporating Fortran 2018. You can also check out Fortran Discourse for further help from experts not here. Commented Jul 14, 2022 at 18:50
  • @Scientist As I wrote in my answer, Fortran compilers are not required to use the standard descriptor for the allocatable components in the derived type structures. Commented Jul 15, 2022 at 11:03

1 Answer 1

4

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I guessed that this would be the answer. If allocatable is not a part of the structure, could it be done? Do you know of anyone who has done some of these 'hacks' that you could point me towards to get started? Thank you for the response!
@CoderJoe1991 The allocatable members are including using a descriptor. The descriptor includes the address of the array, the rank, the size, index ranges... You have to find out the structure of these descriptors and you could access the field directly. The problem is that internally, every compiler can use its own structure for the descriptors. There is a standard descriptor for passing allocatable arrays as bind(C) array arguments, but internally, the compiler can use something else and you have to hack the access to these components.
You also need to know the layout of the individual members in the structure and any padding that the compiler may use for better memory alignment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.