Mixing MS C/C++ with MS FORTRAN--MS-DOS ApplicationsLast reviewed: July 17, 1995Article ID: Q85317 |
The information in this article applies to:
SUMMARYIt is possible to use Microsoft C/C++ version 7.0 to make calls to Microsoft FORTRAN version 5.1. Microsoft C/C++ can issue calls to FORTRAN subroutines or functions, directly from the body of the C/C++ program or from the classes defined or derived. If the FORTRAN functions are included as member functions, they must be wrapped with a C++ member function first; that is, a C++ function should call the FORTRAN code because FORTRAN does not support the calling conventions used in C++ member functions. The call to the FORTRAN language can be issued in the CONSTRUCTOR, DESTRUCTOR, or member function definition section. Although FORTRAN or C functions cannot be overloaded for different kinds of argument types and numbers of parameters, a member function of the CLASS object can be overloaded, and this overloaded function will in turn call the appropriate FORTRAN function that matches the arguments.
MORE INFORMATIONWhen linking with the Microsoft C/C++ 7.0 compiler, the FORTRAN run-time library must be a C-compatible version. The following link response-file should be used:
LINK @CPPFORT.LNK CPPFORT.LNKCPPMAIN.OBJ FORTRAN.OBJ CPPTEST.EXE NUL /NOD /NOE LLIBCE.LIB LLIBFERC.LIB OLDNAMES.LIB; Note: CPPMAIN is the C/C++ object module(s), and FORTRAN.OBJ is the FORTRAN object module(s). LLIBCE.LIB and OLDNAMES.LIB are the run-time libraries for the C/C++ code, and LLIBFERC.LIB is the C-compatible FORTRAN run-time library. Alternatively, LLIBC7.LIB and LLIBF7RC.LIB can be used (where LLIBF7RC.LIB is C-compatible). Is important to note the order in which the libraries are listed; the C/C++ libraries MUST be listed first, followed by the FORTRAN library, followed by any third-party library or user-defined library. If this order is not followed, there will be a number of multiply defined symbols coming from the C/C++ run-time library. It is also required to use the linker provided with the C/C++ compiler. The linker provided with the FORTRAN 5.1 compiler does not support the format for the C/C++ run-time library; if used, it generates an Invalid Object Module error on the C/C++ object files, because older versions of LINK do not understand the information used for C/C++ object files. Below is a sample C++ program that defines a class COMPLEX for manipulating complex numbers. The class invokes a FORTRAN function for calculating the complex number. Note that the FORTRAN function has been declared with the EXTERN "C" attribute to prevent the C++ compiler from generating the call to the FORTRAN functions using C++ naming conventions.
Sample Code 1
#include <iostream.H>typedef struct tagCOMPLEXNUM { float real; float imag; } COMPLEXNUM;extern "C" { extern void __fortran CmpRoot (COMPLEXNUM * num); }class Complex { public : // Class constructors Complex (); // Default constructor Complex (float r, float i); // Constructor with arguments // Class member functions friend Complex operator+(Complex A, Complex B); Complex SqRoot (); // Square root of a complex void display () const; // Show formatted complex number // Private data members private : COMPLEXNUM num; };Complex Complex::SqRoot () { COMPLEXNUM A; A.real = this->num.real; // Use current object's real number A.imag = this->num.imag; // Use current object's imaginary number CmpRoot (&A); // call FORTRAN subroutine return Complex (A.real, A.imag); // Return complex object }Complex operator+ (Complex A, Complex B) { Complex Temp; Temp.num.real = A.num.real + B.num.real; Temp.num.imag = A.num.imag + B.num.imag; return Temp; // Return complex object } void Complex::display() const { // This subroutine display the complex number in an (a, bi) format cout << "(" << num.real << ", " << num.imag << "i)"; }Complex::Complex (float r, float i) { num.real = r; // Constructor with arguments: num.imag = i; // Initialize each member in the COMPLEXNUM } // data structureComplex::Complex () { // Default constructor: num.real = 1.0F; // Initialize real part to 1.0 num.imag = 1.0F; // Initialize imaginary part to 1.0 } void main () { Complex Var1(3.0F, 5.0F), // Call constructor with arguments Var2, // Call default constructor Result; // Call default constructor cout << "The object Var1 contains: "; Var1.display (); // Call member function display() cout << endl; cout << "The object Var2 contains: "; Var2.display (); // Call member function display() cout << endl; cout << " Adding Var1 + Var1: "; Result = Var1 + Var2; // Use the overloaded + operator // to add the objects Result.display (); // Call member function display() cout << endl << endl; cout << "The Square Root of the Complex Object Var1: "; Result = Var1.SqRoot (); // Call member function SqRoot() to // find the square root of the object Result.display (); // Call member function display() cout << endl; } Source Code 2
SUBROUTINE CmpRoot (A) COMPLEX A A = SQRT(A) ! Use the internal FORTRAN square ! root function for complex numbers RETURN ENDc Note: c FORTRAN's built-in type COMPLEX, can be represented in C/C++ c as a structure with two float data members. The first element c in the structure represents the real part, and the second c element represents the imaginary part.
Project MakefileALL : Sample.EXE Sample.EXE : Sample.OBJ ForSub.OBJ Link Sample.OBJ ForSub.OBJ,, NUL, /NOD LLIBCE OldNames LLIBFERC;Sample.OBJ : Sample.CPP CL /AL /c Sample.CPPForSub.OBJ : ForSub.FOR FL /AL /c ForSub.FOR |
Additional reference words: kbinf 5.10 7.00
© 1998 Microsoft Corporation. All rights reserved. Terms of Use. |