Mixed Language Programming - e**x crashes
R**3 via Digitalmars-d-learn
digitalmars-d-learn at puremagic.com
Sat Nov 15 12:49:55 PST 2014
Programming old-timer (but D newbie) with an interesting problem.
Have been doing some playing around with D (DMD v2.066.0)
calling FORTRAN. Asked at the SilverFrost FTN95 Support Forum,
kicked some ideas around, no differences. I realize that a
definitive answer will be difficult since I am combining products
from 2 different suppliers.
If I have done something that is so ignorant that it is a
monumental fail, please be gentle ;-).
when the following is used as real function in FORTRAN
main program (ENG0010.exe) the following 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
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]
Have successfully called other float/REAL*4 FORTRAN functions
from both
D command line and Windows programs (please see
http://rrroberts.50webs.com/cobindex.htm#DCALLS for example
links; please see
http://rrroberts.atwebpages.com/stf95cob.htm#DATAEQV for the
Application Binary Interface).
It was suggested to load salflibc.dll (think of it as SilverFrost
run-time library) at the start; so added
LoadLibraryA ("C:\\Program Files\\Silverfrost\\FTN95
Express\\salflibc.dll");
immediately after the data declaration. No change.
When dmath.exe profiled with Dependency Walker, noticed many
calls to DllMain (yes, familiar with D's DllMain in user-written
D .dlls; Silverfrost FTN95 uses LibMain). Also, received the
following error:
Second chance exception 0xC0000090 (Float Invalid Operation)
occurred in "SALFLIBC.DLL" at address 0x0053EB0A.
It appears that using a D main program to call ERCT (C,R,t) in
user-written mathproc.dll, which in turn calls functions in the
Silverfrost salflibc.dll, causes something to "stepped on" on the
FORTRAN side. This issue also applies to SINH(), COSH(), TANH().
Have been toying with idea of using Sliverfrost C compiler to add
a DllMain to mathproc.dll, though not sure what that would
accomplish.
Any suggestions will be greatly appreciated.
Thanks.
More information about the Digitalmars-d-learn
mailing list