digitalmars.D.learn - Mixed Language Programming - e**x crashes
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.
Nov 15 2014
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