Community
cancel
Showing results for 
Search instead for 
Did you mean: 
Highlighted
Beginner
1 View

Fortran Calling C Example Docs

In https://software.intel.com/en-us/fortran-compiler-developer-guide-and-reference-standard-fortran-and-c-interoperability I copied code and changed only to cpp with extern"C". Iam getting error that I don't understand: error #6646: ALLOCATABLE or POINTER attribute dictates a deferred-shape-array.   [RECVCOUNTS].

Fortran

!********************************
module ftn_C_2
   interface 
     integer (C_INT) function CPP_Library_Function & 
     (sendbuf, sendcount, recvcounts) & 
        BIND(C, name='CPP_Library_Function') 
        use, intrinsic :: ISO_C_BINDING  
        implicit none 
        type (C_PTR), value :: sendbuf 
        integer (C_INT), value :: sendcount 
        type (C_PTR), value :: recvcounts 
     end function CPP_Library_Function 
   end interface 
end module ftn_C_2
!  ftn_c.f90 
!
!  FUNCTIONS:
!  ftn_c - Entry point of console application.
!

!****************************************************************************
!
!  PROGRAM: ftn_c
!
!  PURPOSE:  Entry point for the console application.
!
!********************************************
program ftn_c
use, intrinsic :: ISO_C_BINDING, only: C_INT, C_FLOAT, C_LOC 
use ftn_C_2 
implicit none

! Variables
INTEGER :: CRET
real (C_FLOAT), target :: send(100) 
integer (C_INT) :: sendcount 
integer (C_INT), ALLOCATABLE, target :: recvcounts(100)

!
! Body of ftn_c
    ALLOCATE( recvcounts(100) ) 
!
    CRET = CPP_Library_Function(C_LOC(send), sendcount, C_LOC(recvcounts)) 
!
    print *, 'Hello World'
end program ftn_c

CPP

extern "C" int CPP_Library_Function(void* sendbuf, int sendcount, int *recvcounts) {
	return 0x11;
};

 

0 Kudos
4 Replies
Highlighted
Valued Contributor III
1 View

Given the ALLOCATABLE

Given the ALLOCATABLE attribute of 'recvcounts' array, the compiler is asking you to declare it using the deferred shape notation i.e., using colon syntax ":" rather than as fixed-size:

integer (C_INT), ALLOCATABLE, target :: recvcounts(:)

 

0 Kudos
Highlighted
Black Belt
1 View

The example is wrong. The

The example is wrong. The declaration of revcounts should be (:), not (100).

It's also a terrible example and its style should not be followed. I'll forgive, somewhat, the use of a C_PTR passed by value for the sendbuf argument, as until version 16 that was probably the best way to do that. I won't forgive use of C_PTR by value for recvcounts, this is just an INTEGER(C_INT) without VALUE.

Nowadays sendbuf should be declared in the interface as TYPE(*). In the caller, recvcounts doesn't need the TARGET attribute and should just be passed normally, not with C_LOC.

It's interesting that I have never seen this example before. I'll write up a request for an update/correction and send it to Intel.

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

Thanks to both "best" answers

Thanks to both "best" answers. Is there documentation anywhere for current best interop practices?

0 Kudos
Highlighted
Black Belt
1 View

I don't know of documentation

I don't know of documentation, but my view is "simpler is better". There's rarely need to fuss with C_PTRs, though sometimes it's required. Use the features the language provides, including TYPE(*) for void. Use VALUE only when the C prototype uses by-value. Be careful about character arguments, especially now that CHARACTER(*) is allowed in an interoperable interface, but it requires use of a "C descriptpor" on the C side.

I gave a presentation at the University of Tokyo recently on Fortran 2018, including the interop stuff. I'll post that in a separate topic. (Intel Fortran 16 and later supports all of the F18 interop features.)

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