Allocating memory in C for a Fortran allocatable

后端 未结 3 1506
佛祖请我去吃肉
佛祖请我去吃肉 2021-01-16 06:33

We are trying to take over the memory allocation of a legacy Fortran code (+100,000 lines of code) in C++, because we are using a C library for partitioning and allocating d

3条回答
  •  挽巷
    挽巷 (楼主)
    2021-01-16 07:15

    The internal representation of fortran arrays is very different than the one used in C/C++.

    Fortran uses descriptors that start with a pointer to the array data, and followed by element type size, number of dimensions, some padding bytes, an internal 32/64 bit byte sequence indicating various flags such as pointer, target, allocatable, can be deallocated, etc. Most of these flags are not documented (at least in ifort that I have worked with), and at the end is a sequence of records, each describing the number of elements in the corresponding dimension, distance between elements, etc.

    To 'see' an externally created array from fortran, you'd need to create such descriptors in C/C++, but, it does not end there because fortran also makes copies of them in the startup code of each subroutine before it gets to the first one of your statements, depending on indicators like 'in', 'out, 'inout', and other indicators used in the fortran array declaration.

    Arrays within a type declared with specific sizes map well (again in ifort) to corresponding C struct members of the same type and number of elements, but pointer and allocatable type members are really descriptors in the type that need to be initialized to the correct values in all their fields so fortran can 'see' the allocatable value. This is at best tricky and dangerous, since the fortran compiler may generate copy code for arrays in undocumented ways for optimization purposes, but it needs to 'see' all the involved fortran code to do so. Anything coming outise of the fortran domain, is not known and can result in unexpected behavior.

    Your best bet is to see if gfortran supports something like iso_c_binding and define such interfaces for your fortran code, and then use iso_c_binding intrinsics to map the C_PTR pointers to fortran pointers to types, arrays, etc.

    You can also pass a pointer to a one-dimensional array of char, and its size, and this works for strings mostly as long as the size is passed by value as last argument (again, compiler and compiler-flag dependent).

    Hope this helps.

    EDIT: changed 'ifort's iso_c_binding' to 'iso_c_binding after Vladimir's comment - thanks!

提交回复
热议问题