Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
21 Views

Passing 2D array from C++ to Fortran

Not really a problem, I just want some assessment of my method for passing multidimensional array from C++ main program to a Fortran subroutine.

The C++ code reads

#include <iostream>                                                                                                                        
                                                                                                                                           
extern "C"                                                                                                                                 
{ void FTN_for_sub2(const long int *, const long int *, const double *);}

int main()                                                                                                                                 
{                                                                                                                                                                                                                                                                
  long int m=2;                                                                                                                            
  long int n=3;                                                                                                                                                                                                                  
  double z;                                                                                                                          
                                                                                                                                           
  z[0][0] = 1.0;                                                                                                                           
  z[0][1] = 5.0;                                                                                                                           
  z[0][2] = 6.0;                                                                                                                           
  z[1][0] = 3.0;                                                                                                                           
  z[1][1] = 2.0;                                                                                                                           
  z[1][2] = 10.0;                                                                                                                                                             
                                                                                                                                                                                                                                              
  FTN_for_sub2(&m, &n, &z[0][0]);                                                                                           
                                                                                                                                            
  return 0;                                                                                                                                
}                                                                                                                                          

whereas the Fortran routine is

subroutine FOR_SUB2(m, n, z) bind(C, name="FTN_for_sub2")                                                                         
  use, intrinsic :: iso_c_binding                                                                                                          
  implicit none                                                             
  integer(c_long), intent(in) :: m, n                                          
  real(c_double), intent(in) :: z(n,m)       ! z must declared as z in the C++ side.                                                 
                                                                                                                                           
  character :: dummy_str*4, fmt*100                                                                                                        
  integer(c_long) :: i
 
  write(dummy_str, "(i4)") m 
  fmt = "("//trim(adjustl(dummy_str))//"f12.4)"
  do i = 1,n
     write(*,fmt) z(i,1:m)
  end do                                                                                                                                                                                                                                                                              
                                                                                                                                           
end subroutine FOR_SUB2    

These codes compiled and ran well but one thing that still bothers me is the way I pass 2D array z from C++ side which is

&z[0][0] 

I searched many resources about passing multidimensional array from C++ to Fortran and I never encountered my method suggested in any of those sources. My question is are there any drawbacks in my method, is it frowned upon or something else?

0 Kudos
5 Replies
Highlighted
Black Belt
21 Views

Fortran uses column-major

Fortran uses column-major storage order, C uses row-major order. See https://en.wikipedia.org/wiki/Row-_and_column-major_order .

As long as your C and Fortran source codes handle the arrays correctly in conformity with the rules of each language, there is no reason to frown on the code. On the other hand, if you wish to write subroutines/functions that have to process 2-D arrays of arbitrary dimensions, you will need full awareness of the differences between the two languages and the calling conventions of the compiler+platform.

When array arguments are passed to subroutines, Fortran allows you several ways in which to pass information regarding the extents of the array indices, whether the array may be allocated or its allocation changed, etc., and C does not do things in the same ways. Fortran 2003 and 2008 provide an extensive set of rules and facilities for interoperability with C.

 

0 Kudos
Highlighted
Beginner
21 Views

I asked that because I am

I asked that because I am about to write a moderate size project mixing C++ and Fortran. I am new to C++, let alone the interoperability issues with Fortran. Until now in Fortran I almost always declare dummy array arguments to be of assumed-shape but then I learned that assumed-shape is not interoperable with C/C++. Some examples use assumed-size but to me assumed-size declaration is not quite elegant. That's why I decided to use adjustable type.

0 Kudos
Highlighted
Black Belt
21 Views

Assumed-shape is now

Assumed-shape is now interoperable with C, but on the C side it must process it using a "C descriptor" as declared in ISO_Fortran_binding.h that Intel Fortran supplies. This is a Fortran 2018 feature supported as of version 16.

--
Steve (aka "Doctor Fortran") - https://stevelionel.com/drfortran
0 Kudos
Highlighted
Beginner
21 Views

Ok I will take a look, but is

Ok I will take a look, but is this header file usable from C++ code too?

0 Kudos
Highlighted
Black Belt
21 Views

Yes, you can use the header

Yes, you can use the header file in C++ code. If you look at the file itself, you will see the following near the beginning

#if defined(__cplusplus)
extern "C" {
#endif

and matching conditionally included code near the end of the file to supply the closing "}".

0 Kudos