Problem
I am trying to have a function be the argument to another function however I keep getting the error:
Error: Internal procedure 'polytrope' is not allowed as an actual argument at (1)
Code
Bellow is a barebones version of the program making the call to the function and which contains the actual callback:
PROGRAM testbutcher
USE butcher
IMPLICIT NONE
REAL :: t = 0, dt = 0.01
REAL, DIMENSION(2) :: v0 = (/ 1.0, 0.0 /), fargs 开发者_如何学Python= (/ 1.0, 1.0 /)
v0 = step(polytrope, v0, 2, t, dt, fargs)
CONTAINS
FUNCTION polytrope(v0, t, fargs) result(v1)
REAL, DIMENSION(:) :: fargs
REAL, DIMENSION(2) :: v0, v1
REAL :: t
v1 = t * v0
RETURN
END FUNCTION
END PROGRAM
and then the module which the function taking the functional argument is:
MODULE butcher
IMPLICIT NONE
CONTAINS
FUNCTION step(fxn, v0, n, t, dt, fargs) RESULT(v1)
REAL, DIMENSION(n) :: v0, v1
REAL, DIMENSION(:) :: fargs
REAL, DIMENSION(tn,tm) :: tab
REAL :: t, dt
INTEGER :: n, tn, tm
INTERFACE
FUNCTION fxn(v, t, fargs)
REAL, DIMENSION(:), INTENT(in) :: v
REAL, DIMENSION(:), INTENT(in) :: fargs
REAL, INTENT(in) :: t
END FUNCTION
END INTERFACE
v1 = fxn( v0, &
t + dt, &
fargs &
)
RETURN
END FUNCTION
END MODULE
Summary
So basically, testbutcher contains a function to be evaluated in a special way, so it sends it off to the module butcher (specifically the function step in butcher) to be evaluated. I can't figure out how to actually do this! If I were working in C i would simply make a pointer to polytrope and throw it to fxn.
In the function step, you define the inputs to fxn as being of INTENT(IN), but you don't declare any intent in your function polytrope. Also, the return type of fxn is not specified so it is being implicitly defined and won't be compatible with "REAL, DIMENSION(2)". I think you need a few more "IMPLICIT NONE" declarations in your code to catch this error.
This is what has worked for me in the past with all of MS Fortran, Digital Fortran, Intel Fortran, and gfortran:
- Declare the function as external to the module that uses it.
- Declare the function proper outside any module (it could go in its own file).
It's what I use to declare a library-invoked 'usage' subroutine in every program. It is likely that the compiler won't check that the function's signature is correct unless you also use an INTERFACE
statement (which is not a bad idea).
PROGRAM testbutcher
USE butcher
IMPLICIT NONE
EXTERNAL polytrope !!!!!
REAL :: t = 0, dt = 0.01
REAL, DIMENSION(2) :: v0 = (/ 1.0, 0.0 /), fargs = (/ 1.0, 1.0 /)
v0 = step(polytrope, v0, 2, t, dt, fargs)
CONTAINS
END PROGRAM
!!!!!
FUNCTION polytrope(v0, t, fargs) result(v1)
REAL, DIMENSION(:) :: fargs
REAL, DIMENSION(2) :: v0, v1
REAL :: t
v1 = t * v0
RETURN
END FUNCTION
精彩评论