C++ Methods, FORTRAN
Volume Number: 7
Issue Number: 2
Column Tag: Jörg's Folder
C++ Methods In FORTRAN 
By Jörg Langowski, Editorial Board
“C++ Methods in FORTRAN”
This article had to come. Next thing you’ll see, you may think, is calling Eiffel
from Forth. But seriously, implementing cross-language calling very often helps you
to understand how one particular language really works and how to get most out of it.
Also, the Fortran run time system has some advantages, like well-designed console I/O
that may help in debugging, file I/O, an easily accessible output window, and therefore
adding it may be very helpful in some applications. So here we go, and write a C++
method in Language Systems Fortran.
C++ methods are really independent subroutines, and the association between a
method and its class is done through the header file - on the source code side - and
through the modified method name on the object code side. When you define two
different classes with methods of the same name, as in
// 1
class aaa {
public:
void doit();
}
class bbbb {
public:
void doit();
}
the methods are usually defined in a place different from where they are actually used.
In fact, most often they may be pre-compiled in a library. The linker can distinguish
between the two different doit methods, because their symbolic name on the linker level
is modified by the class name. The two methods’ names in this case would be:
doit__3aaaFv and doit__4bbbbFv.
C++ Function Name Encoding
To remind you of the C++ linker naming conventions: the first part of the linker
name is the method name (doit), followed by two underscores. Then follows the class
name, preceded by the number of characters in that name. Appended to that are some
symbols describing the parameter list. In our case, for methods taking no parameters,
it is simply “Fv”. F stands for a function, v for a void parameter list. I am not
describing all the modifiers that are used in creating a linker name out of a C++ method
name; the full encoding scheme is described in the AT&T C++ release notes, chapter 6,
page 22.
Usually, you never see the encoded names; only when e.g. a method is defined in a
class header file, then referenced by some code using objects from that class, but never
actually implemented, the linker might complain about a missing function. There, you
will probably have seen those funny names already, and used the MPW unmangle tool to
make sense out of them.
Here, we want to go the other direction. When we implement a C++ method in
some non-object language, we must write a routine that has the encoded method’s name.
The easiest way to find out about the linker name of a C++ method is not to construct it
yourself (you never get it right in the first place), but just to define the method in the
class header, use it in the code, and never actually implement it. The linker will tell
you in its error message what function it is looking for.
That way I found out that the name for the method pascal void FtnCall() in the
class TMacTutorDocument is FTNCALL__17TMACTUTORDOCUMENT. The characters
“Fv” are not appended here, and the name is written in all capitals, because of the
“pascal” keyword. This also means that all external Pascal-type methods of the same
name in the same class will have the same linker name, regardless of the argument list.
The linker will tell you in its error message what function it is looking for.
Language Systems Fortran, of course, uses Pascal calling conventions, so a
method written in Fortran will have to be defined in C++ as pascal. We want to pass
some parameters, so lets define an argument list:
{2}
pascal void FtnCall(short *menuitem, long k, float *r);
The method will later be called from a menu handler, just for the fun of it, and
we pass the number of the menu item selected, and some numbers. Note one restriction
here: LS Fortran symbolic names are limited to 31 characters, so don’t use too
complicated class and method names if you don’t want to run out of space.
The Sample Program
We use the sample program that I showed you in V6#1: Apple’s C++
mini-application skeleton. You should now go back to your library and get that MacTutor
issue, or reorder it, because we obviously cannot reprint its full source here. Listing
2 only shows those parts that have been changed.
In the constructor and destructor methods of the application class we have added
calls to InitFortran() and ExitFortran() for initializing the Fortran run time system
at the start of the program and leaving it properly at the end. During the program,
then, the run time system is at our disposal. The Fortran method is defined in the class
TMacTutorDocument. It is used in the TMacTutorApp class, in its DoMenuCommand
method:
// 3
x = 4.567;
fMacTutorCurDoc->FtnCall(&menuItem,3456,&x);
This way we have some calls by reference (standard Fortran calling convention),
and one call by value.
The Fortran routine (listing 1) receives the three parameters in the same
order. Furthermore, on every method call a handle to the method’s current object
(this) is pushed on the stack after all the method’s parameters. The Fortran code has to
take that extra parameter into account. Thus, the first line of the Fortran routine will
be
C 4
subroutine FTNCALL__17TMACTUTORDOCUMENT
(menuitem,%val(k),r,%val(this)) .
menuitem and r are passed by reference, k is received by value (Language
Systems Fortran has an option for receiving parameters by value in the subroutine
definition). this is also received by value. Through this, we can access the instance
variables of the method’s current object. We also define the list of instance variables,
which becomes rather complicated as we have to dereference handles in the (Languages
Systems) Fortran way. The structure definitions at the beginning of the Fortran routine
show you how to do that.
this points to the beginning of the object’s instance variables, starting with
those of the topmost ancestor class and descending through the class hierarchy. In our
case, we have a window pointer fDocWindow and the pointer to the virtual methods table
vptr from the TDocument class, then the instance variables of TMacTutorDocument,
fItemSelected and fDisplayString.
The main body of the routine displays the passed parameters and some
information about the instance variables in the Fortran output window.
That’s all! You’re now able to add Fortran code to C++ programs as you like, and
have it behave like real C++ methods.
Listing 1: C++ method written in Fortran
C C++ test method written in Language Systems Fortran
C For editing, some of the lines had to be split. I have not
C created proper Fortran continuation lines, because a. C I'm
lazy and b. I think the text can be read better that
C way -- jl --