I am a newcomer to this, but I need to access some old Fortran 77 functions from C. I don't want to alter the Fortran code if possible, I would really prefer to write a wrapper to call the Fortran functions from C. I hope to get a minimal working example (on Linux). What I did:
In file somefunction.f:
REAL*8 FUNCTION MYFUNC(ZZ)
IMPLICIT NONE
REAL*8 ZZ, T1
T1 = ZZ + 1.0D0
MYFUNC = T1
RETURN
END
compiled with gfortran -c somefunction.f -o somefunction.o.
In file debug.c:
#include <stdio.h>
double cfunc(double x) {
double result = myfunc_( &x );
return result;
}
int main() {
double test = cfunc(3.0);
printf(" %.15f ",test);
}
compiled with gcc -c debug.c -o debug.o.
Then I give gcc debug.o somefunction.o and ./a.out.
However, instead of 3+1=4, I get nonsensical numbers. How do I correct this?
P.S: If this is solved, the actual functions I have are a bit more complicated:
What should I change if MYFUNC were to be instead of the type COMPLEX*16 FUNCTION MYFUNC(ZZ) with ZZ also a complex?
What if MYFUNC called some built-in Fortran function, say CDLOG(ZZ) ?
And what if it accesses a common block? Can this be accommodated too?
In addition to the return type, you also need to pay attention to the way the Fortran procedure name is mangled into a symbol that you access from C. There's no standard, it entirely depends on the Fortran compiler and platform, so you'll have to use some configure-time detection and a macro if you want portability.
For example, Fortran MYFUNC() needs to be called from C as:
MYFUNC() under Intel Fortran on Windowsmyfunc() under IBM XL Fortran (xlf)myfunc_() in most other cases (including GNU Fortran on Windows)(It gets even more complicated when the Fortran routine is in a module, because then the mangled name is prefixed by the module and _MOD_, _mp_, etc.)
The modern Fortran solution is to declare a bind(C) routine on the Fortran side, which turns this mangling off (or you can specify an explicit binding name).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With