Mixing MS C/C++ with MS FORTRAN--MS-DOS Applications
ID: Q85317
|
The information in this article applies to:
-
Microsoft FORTRAN for MS-DOS, version 5.1
-
Microsoft C/C++ for MS-DOS, version 7.0
SUMMARY
It 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 INFORMATION
When 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.LNK
CPPMAIN.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 structure
Complex::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
END
c 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 Makefile
ALL : 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.CPP
ForSub.OBJ : ForSub.FOR
FL /AL /c ForSub.FOR
Additional query words:
kbinf 5.10 7.00
Keywords :
Version : :5.1; MS-DOS:7.0
Platform : MS-DOS
Issue type :