Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.
Announcements
FPGA community forums and blogs on community.intel.com are migrating to the new Altera Community and are read-only. For urgent support needs during this transition, please visit the FPGA Design Resources page or contact an Altera Authorized Distributor.
29285 Discussions

Problem calling a dummy callback from Fortran

Adrian_F_1
Beginner
935 Views

I have a problem calling a dummy callback from Fortran.

We have a C++ program which calls Fortran code, EQCONTOUR.
It passes a function pointer (FCALL) when calling this subroutine.
The purpose is to provide a callback function that the Fortran can call back in the C++ world to echo progress, etc.
This all works fine and here is the code:

EQCONTOUR uses this module:

      module GUI_OLI
        implicit none
        save
        interface
          integer function GUI_FCALL(TEMP,PRES,IPT,JPT,KERR)
            REAL*8 , intent(in)  :: TEMP, PRES
            INTEGER, intent(in)  :: IPT, JPT
            INTEGER, intent(out) :: KERR
          end function
        end interface
        pointer (p_GUI_FCALL, GUI_FCALL)
      end module GUI_OLI


Here is EQCONTOUR:

      SUBROUTINE EQCONTOUR(FCALL)
      USE GUI_OLI
      IMPLICIT NONE
      INTEGER    :: FCALL

      p_GUI_FCALL = FCALL
...
      IF(GUI_FCALL(TEMP,PRES,IT,IP,KERR) == 0) THEN
...
      RETURN
      END

This works fine when EQCONTOUR is called from C++.

The problem comes when I want to test calling EQCONTOUR from Fortran.
Here is my code:

      PROGRAM TEST
      IMPLICIT NONE
      INTEGER, EXTERNAL :: FCALL
!
      call EQCONTOUR(FCALL)
      END
! dummy FCALL
      integer function FCALL(TEMP,PRES,IPT,JPT,KERR)
        REAL*8 , intent(in)  :: TEMP, PRES
        INTEGER, intent(in)  :: IPT, JPT
        INTEGER, intent(out) :: KERR
        FCALL = 1
        KERR = 0
      end function

When I try to call from Fortran as above, I get an access violation on the
IF(GUI_FCALL(... line.

I'm not sure why.

0 Kudos
1 Reply
Steven_L_Intel1
Employee
935 Views
You've left out some critical lines - such as what I suspect is: POINTER (p_GUI_FCALL, GUI_FCALL) in EQCONTOUR The way you have coded EQCONTOUR, it is expecting an integer by reference containing the address of the callback routine. This isn't consistent with simply passing the routine has you have in your test program. Try this: PROGRAM TEST IMPLICIT NONE INTEGER, EXTERNAL :: FCALL INTEGER :: p_FCALL p_FCALL = LOC(FCALL) ! call EQCONTOUR(p_FCALL) END I will also comment that your code will fail if built as a 64-bit program because you are assuming 32-bit addresses. I'd prefer to see this rewritten using procedure pointers and the C interoperability features, but you could simply change the INTEGER :: FCALL in EQCONTOUR to INTEGER(INT_PTR_KIND()) :: FCALL and similarly the declaration of p_FCALL I added above. The C code would need to make sure it is passing a pointer and not an int.
0 Kudos
Reply