Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
29277 Discussions

C++ pointer pass to Fortran in Fortran/C++ mixed program

Zhanghong_T_
Novice
1,270 Views
Dear all,

I have some problems in passing C++ pointer to Fortran when working on Fortran/C++ mixed program.

I use the VS2010 to build C++ DLL and Intel Fortran main program. C++ code:

// cppdll.cpp : Defines the exported functions for the DLL application.
//
typedef struct outputobj0
{
int intarraysize;
int doublearraysize;
int *intarray;
double *doublearray;
}outputobj;
extern "C" void C_ASSIGN_ARRAY_TO_FORTRAN(outputobj *obj)
{
obj->intarraysize=10;
obj->doublearraysize=10;
int *intarray=new int[obj->intarraysize];
double *doublearray=new double [obj->doublearraysize];
for (int i=0;iintarraysize;i++)
intarray=i;
for (int i=0;idoublearraysize;i++)
doublearray=i;
obj->intarray=intarray;
obj->doublearray=doublearray;
}

Fortran code:
implicit none
type mystruct
integer::intsize
integer::doublesize
integer,pointer::intarray(:)
real*8,pointer::doublearray(:)
end type

type(mystruct)::test
integer::i

call C_ASSIGN_ARRAY_TO_FORTRAN(test)
write(*,*)test%intsize
write(*,*)test%doublesize
do i=1,test%intsize
write(*,*)test%intarray(i)
enddo
do i=1,test%doublesize
write(*,*)test%doublearray(i)
enddo
end


Results show that the C++ pointer hasn't been passed into Fortran. How to modify the code to let the C++ pointer pass to the Fortran correctly?


Thanks,
Zhanghong Tang


PS: the whole project is also attached.


0 Kudos
4 Replies
TimP
Honored Contributor III
1,270 Views
A Fortran pointer is much more complicated than a C pointer (which is more like a Fortran Cray pointer). You would receive the C pointer as integer(c_ptr) and use c_f_pointer to make a Fortran pointer from it.
0 Kudos
Zhanghong_T_
Novice
1,270 Views
Hi Timp,

Thank you very much for your kindly reply. Could you please help me to modify the code to let the program output the correct result?

I wish the test%intarray and test%doublearray can be used as before.

Thanks,
Zhanghong Tang
0 Kudos
Zhanghong_T_
Novice
1,270 Views
Dear all,

Could anyone tell me how to modify the code to pass the struct to C++ code and let the C++ allocate arrays and then access them by Fortran as usual way (like test%intarray and test%doublearray)?

Thanks,
Zhanghong Tang
0 Kudos
IanH
Honored Contributor III
1,270 Views
Use C interop from F2003.

[fortran]  USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_INT, C_DOUBLE, C_PTR,  &
      C_F_POINTER
  
  IMPLICIT NONE
  
  TYPE, BIND(C) :: MyStruct_C
    INTEGER(C_INT) :: intarraysize
    INTEGER(C_INT) :: doublearraysize
    TYPE(C_PTR) :: intarray
    TYPE(C_PTR) :: doublearray
  END TYPE MyStruct_C
    
  TYPE :: MyStruct
    INTEGER(C_INT), POINTER :: intarray(:)
    REAL(C_DOUBLE), POINTER :: doublearray(:)
  END TYPE MyStruct
  
  INTERFACE
    SUBROUTINE C_ASSIGN_ARRAY_TO_FORTRAN(obj)  &
        BIND(C, NAME='C_ASSIGN_ARRAY_TO_FORTRAN')
      IMPORT :: MyStruct_C
      IMPLICIT NONE
      TYPE(MyStruct_C), INTENT(OUT) :: obj
    END SUBROUTINE C_ASSIGN_ARRAY_TO_FORTRAN
  END INTERFACE
  
  TYPE(MyStruct_C) :: test_c
  TYPE(MyStruct) :: test
  
  !****
  
  CALL C_ASSIGN_ARRAY_TO_FORTRAN(test_c)
  CALL C_F_POINTER( test_c%intarray, test%intarray,  &
      [test_c%intarraysize] )
  CALL C_F_POINTER( test_c%doublearray, test%doublearray,  &
      [test_c%doublearraysize] )  
  
  WRITE (*, *) SIZE(test%intarray)
  WRITE (*, *) SIZE(test%doublearray)  
  WRITE (*, *) test%intarray
  WRITE (*, *) test%doublearray

END 
[/fortran]
0 Kudos
Reply