🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.fortran
Article #4627

Re: How to link Fortran with c++ ??

#4627
From: Carsten Arnholm
Date: Wed, 31 Jan 1996 14:42
186 lines
6402 bytes
Niels Hilbrink <Niels@imacsg1.epfl.ch> wrote:
>Hi,
>
>I have to link a piece of fortran code with c++ code but since if never
>done that before I'd like to know a) can it be done and b) is it
>difficult.
>
>Everything concerning this subject is welcome.
>
>Gr.
>Niels Hiblrink
>
>
>-- 
>
>   The most overlooked advantage to owning a computer is 
>   that if they foul up there's no law against wacking   
>   them around a little.                                 
>
>------------------------------------------------------------
>Koen D'Hondt			              Niels Hilbrink
>koen@@dutlhs1.lr.tudelft.nl      niels@dutlcc3.lr.tudelft.nl
>
>**** Ripley Software Development ****
>(finger niels@dutlcc3.lr.tudelft.nl for more information.)
>------------------------------------------------------------

Hi there,


Mixed language programming (C++/FORTRAN 77) is not as hard as 
it may seem.

The only non-trivial problem you must solve is fortran CHARACTERs. 
You need to write a minimal CHARACTER class in C++. 

If you require single-source portability, it becomes slightly
more complicated, but not impossible.

Below follows a summary of some stuff that I have done, plus
some additional thoughts. 



typedef int     INTEGER;
typedef float   REAL;
typedef int     LOGICAL; 

#include "character.h"  // CHARACTER class (see below)

#define  SUBROUTINE        extern "C" void __stdcall
#define  INTEGER_FUNCTION  extern "C" INTEGER __stdcall
#define  REAL_FUNCTION     extern "C" REAL __stdcall



The CHARACTER class may look something like this:



#include <string.h>

/*
  class CHARACTER
  ===============
  A minimal class used when passing C-string arguments from C++ to
  FORTRAN 77 (received as FORTRAN 77 CHARACTER strings), and subsequently
  returned back to C++ as properly zero terminated c-strings.

  Method used for zero-termination:
  =================================
  When the CHARACTER destructor is activated (typically when the
  CHARACTER object goes out of scope within a C++ stub function)
  the zero-termination of the c-string is automatically managed.

  FORTRAN Assumptions:
  ====================
  (1) FORTRAN truncates assigned strings when CHARACTER variable is too short
  (2) FORTRAN pads CHARACTER variable with blanks when assigned string is short
  (3) FORTRAN represents a CHARACTER as a string pointer followed by a length

  Author: Carsten A. Arnholm, 20-AUG-1995
*/

class CHARACTER {
public:
    CHARACTER(char* cstring) : rep(cstring), len(strlen(cstring)) {};
    CHARACTER(char* cstring, const size_t lstr);
   ~CHARACTER();
public:
    char*   rep;  // Actual string
    size_t  len;  // String length, used by FORTRAN intrinsic function LEN()
};

inline CHARACTER::CHARACTER(char* cstring, const size_t lstr) : rep(cstring), len(lstr-1)
{
   size_t actual = strlen(rep);
   for(size_t i=actual;i<len;i++) rep[i]=' ';
   rep[len]='\0';
}

inline CHARACTER::~CHARACTER() {
   for(size_t i=strlen(rep)-1;i>=0;i--) {
     if(rep[i] != ' ') {
        rep[i+1] = '\0';
        break;
     }
   }
}


now you can declare FORTRAN subroutine prototypes in C++:

SUBROUTINE MYSUB(INTEGER& I1, CHARACTER C1, INTEGER& I2);

To create a portable solution, do the following:

a) Write header files for your FORTRAN libraries as shown above.
b) Compile FORTRAN code and create *.lib files.
c) Include the FORTRAN library header files in your C++ code.
d) Call FORTRAN according to above prototype example.
e) Compile C++ code and link with FORTRAN libraries
f) This executes directly for Visual C++ 2.1 & 4.0 in combination
   With Fortran Powerstation

porting to other machines:

a) Leave C++ and Fortran code untouched (single source requirement!)
b) Write a small C++ program that read your FORTRAN library header files, 
   and generate:
   b.1: a platform-specific header file for the fortran
        library. Here you deal with upper/lowercase names,
        trailing underscores, character lengths etc.
   b.2: a platform-specific *.CPP file containing inline
        functions that convert from 
        MYSUB(INTEGER& I1, CHARACTER C1, INTEGER& I2)
        to
        mysub_(int& I1, char* C1.rep, int& I2, int C1.len)

        (example above is for for SGI)
c) Compile & link this generated code with your application.
e) Should execute on basically any platform (UNIX, VMS, ...)


Other issues
============

a) Calling/linkage convention (C++).
   This is taken care of through the use of the statement: extern "C"
   This avoids name mangling which is not used in FORTRAN.

b) Routine names
   An ANSI standard FORTRAN routine name should be defined in UPPERCASE
   and max 6 characters. This does not, however, mean that the name
   used when calling from C/C++ should be in uppercase. On the SGI machine
   (i.e. unix) the routine must be in lowercase with a trailing underscore.
   On other unix boxes, you may need a leading underscore and/or uppercase
   name.

   Example:
   FORTRAN                              :          SUBROUTINE MYSUB
   Machine-dependent C++ prototype (SGI):     extern "C" void mysub_();

c) Parameter types and argument passing
   FORTRAN will always require parameters to be passed by reference
               
   FORTRAN                              :  SUBROUTINE MYSUB(IVAL)
                                           INTEGER          IVAL

   Machine-dependent C++ prototype (SGI):  extern "C" void mysub_(int& IVAL);


d) Machine dependent comparison of language types:

   FORTRAN               C++ 
   =======               ===
   INTEGER               int&
   REAL                  float&
   LOGICAL               int&
   CHARACTER             char*   (+ size_t length )
   DOUBLE PRECISION      double&

good luck,

Carsten Arnholm
ca@sesam.dnv.no 
Technical Details
Message-ID: <4env5h$3ai@nms.telepost.no>
Path: arc1-ca.pugleaf.net!telepost.no!usenet
References: <310DD74F.59E2@imacsg1.epfl.ch>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!telepost.no!usenet
From: Carsten Arnholm <ca@sesam.dnv.no>
Newsgroups: comp.lang.fortran,comp.lang.c++
Subject: Re: How to link Fortran with c++  ??
Date: 31 Jan 1996 14:42:57 GMT
Organization: DNV
Message-ID: <4env5h$3ai@nms.telepost.no>
References: <310DD74F.59E2@imacsg1.epfl.ch>
NNTP-Posting-Host: hugin.sesam.dnv.no
Mime-Version: 1.0
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
X-Mailer: Mozilla 1.1 (Windows; I; 32bit)