## digitalmars.D.learn - Mixed Language Programming - e**x crashes

• R**3 (89/89) Nov 15 2014 Programming old-timer (but D newbie) with an interesting problem.
• Kagamin (4/4) Nov 16 2014 Well, the easiest thing is to see assembler generated at both
"R**3" <rrobe71907 aol.com> writes:
```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
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
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
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.
```
Nov 15 2014
"Kagamin" <spam here.lot> writes:
```Well, the easiest thing is to see assembler generated at both
sides and check if they are compatible. If they are not, try to
interface via C ABI. You can also inspect value of X before
calling EXP.
```
Nov 16 2014