Have an interesting problem. Over the years, have done a lot of mixed language programming (main program written in one language calling a subroutine written in another; subroutines written in different languages calling each other) on a couple of different platforms.
Currently playing with D main programs calling FORTRAN subroutines.
when the following is used as real function in FORTRAN main program (ENG0010.exe) the function runs fine
C Series Resistance Capacitance Circuit C Resistance Capacitance Time C T : Seconds C R : Ohms C C : Farads REAL FUNCTION ERCT (T, R, C) RESULT (X) REAL T, R, C, X X = T / (R * C) X = EXP(X) RETURN END FUNCTION ERCT
when used in a .dll (mathproc.dll) called by a D command line program (dmath.exe, compiled with DMD dmath.d mathproc.lib), function crashes at X = EXP(X) with object.Error@(0): Invalid Floating Point Operation in RegisterWaitForInputIdle (I suspect that is a DMD v2.066.0 compiler specific message/error)
The FORTRAN main program: PROGRAM ENG0010 IMPLICIT NONE
REAL E, T, R, C, L, I, ERCT, VCAP, V, TMP
C = 0.000018;
R = 8100.0;
E = 20.0;
T = 0.31;
TMP = ERCT (T, R, C)
PRINT '(a,F7.2)',' ERCT (T, R, C): ', TMP
V = VCAP (E, T, R, C)
PRINT '(a,F7.2)',' VCAP (E, T, R, C): ', V
END
The D main program: import std.stdio;
// mathproc.dll subroutine declarations extern (Pascal) { float ERCT (ref float, ref float, ref float); float VCAP (ref float, ref float, ref float, ref float); }
int main(string[] args) { float C, R, t, E, L, V, I, tmp;
C = 0.000018;
R = 8100.0;
E = 20.0;
t = 0.31;
tmp = ERCT (C,R,t);
printf (' ERCT (C,R,t): %f \\n', tmp);
V = VCAP(C,R,t,E);
printf (' VCAP(C,R,t,E): %f \\n', V);
return (0);
}
[extern (Pascal) requires the parameters passed in reverse order; this was the only way I could get the D mains/FORTRAN .dll's compile/link cleanly]
Dependency Walker shows the ENG0010.exe version calls _FTN95INIT1, dmath.exe does not.
When dmath.exe profiled with Dependency Walker, received the following error: Second chance exception 0xC0000090 (Float Invalid Operation) occurred in 'SALFLIBC.DLL' at address 0x0053EB0A.
Have successfully called other float/REAL4 FORTRAN functions from both D command line and Windows programs; only time I have seen similar errors was when I should have used REAL8 instead of REAL*4, so tried that correction; same result.
Can think of several possibilities:
- I am blind and cannot see an obvious error
- I need to call some sort of floating point initializer or arithmetic trap; is it possible to call _FTN95INIT1 (or its equivalent) directly?
- D calling FORTRAN function EXP(X) may have some minor eccentricity/incompatibility.
Would someone like to admit my ignorance for me? 😉 Would not be surprised if I did something goofy. 😉
Thanks for reading this post.
