
MODULE FortranLib

  IMPLICIT NONE
  
  PRIVATE
  
  ! Just to be clear on our intention for this procedure to be called from 
  ! outside the module.
  PUBLIC EntryPoint
  
  INTERFACE
    ! Interface back to the C++ side
    FUNCTION TheCppFunction(ptr, arg) RESULT(val)  &
        BIND(C, NAME='fn_for_fortran_to_call')        
      USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR, C_DOUBLE
      IMPLICIT NONE
      TYPE(C_PTR), INTENT(IN), VALUE :: ptr
      REAL(C_DOUBLE), INTENT(IN) , VALUE :: arg 
      REAL(C_DOUBLE) val
    END FUNCTION TheCppFunction
  END INTERFACE

CONTAINS

  ! Out fortran entry point.
  SUBROUTINE EntryPoint(ptr) BIND(C, NAME='fortran_entry_point')
  
    USE, INTRINSIC :: ISO_C_BINDING, ONLY: C_PTR
    
    TYPE(C_PTR), INTENT(IN), VALUE :: ptr
    
    REAL the_result
    
    !***************************************************************************
    
    WRITE (*, 100) 'Fortran begins'
    ! We pass the C-pointer that we were given back to the C++ function.
    the_result = TheCppFunction(ptr, 3.0)
    WRITE (*, 110) the_result
    WRITE (*, 100) 'Fortran ends'
    
    100 FORMAT(A)
    110 FORMAT('The result of the intensive calculations was:',G10.2)
    
  END SUBROUTINE EntryPoint
  
END MODULE FortranLib
