Using FORTRAN in your DLL |
It is possible to wrap compiled FORTRAN code in C or C++, allowing Mathcad to run it. In this way, legacy FORTRAN code can be reused as a Mathcad function. We have had success compiling with Compaq Visual Fortran (formerly MS Fortran) and MS Visual C++ 6 or 7.
First, follow the directions for Compiling and Linking your DLL to set up the Visual Studio environment with all the appropriate settings for creating a UserDLL. Next, create a static library from the FORTRAN subroutine. Link the C code to the FORTRAN code, and compile a DLL in the usual manner for Mathcad use.
Once you have the FORTRAN library, you need to add in your C code:
extern void __stdcall FORTRANFUNCTION(const double *array1, const double *scalar1 [, etc.]);
// Since FORTRAN typically expects arguments by reference, arguments are passed
// as pointers. To pass values, the FORTRAN code must contain a compiler directive
// telling the function to expect a value rather than an address.
LRESULT mcadfunction(LPCOMPLEXARRAY array1, LPCCOMPLEXSCALAR scalar1, etc.)
// this defines the function before FUNCTIONINFO, using the same variable names
// called by the external FORTRAN function.
{
// some error checking goes here, followed by the
// actual call to the FORTRAN function. For example,
FORTRANFUNCTION(&array1->hReal[0][0], &scalar1->real [, etc.]);
// Either the function call must be in UPPERCASE, or you will have to set
// Settings->FORTRAN->External procedures->External name implementation
// to "Upper case" in your FORTRAN compiler. Any other C functionality follows...
return 0;
}
If the FORTRAN code contains "PRINT" to console statements, these can be converted by reassigning console to a file, so output goes to a file instead of the screen. If the FORTRAN routine terminates with an error, the C++ front-end can be programmed to read this "log" file and display it as a window. For example:
SUBROUTINE INIT_STDOUT ()
c this subro which redirects FORTRAN output to file
use dfwin
integer res
c CALL close_stdout
res=SETENVQQ("FOR_PRINT=C:\FORT_OUT.TXT")
c PRINT *, 'Print a character to initialize '
PRINT *,' '
RETURN
END