Re: Root macro call Fortran subroutines

From: Christian Holm Christensen <cholm_at_nbi.dk>
Date: Sat, 26 Aug 2006 12:51:13 +0200


Hi all,

On Fri, 2006-08-25 at 14:26 -0400, Brett Viren wrote:
> "Weijun Guo" <Weijun.Guo_at_halliburton.com> writes:
>
> Halliburton uses Root ?!?

Wonder if they realise that it's GNU LGPL'ed :) - Weijun, don't take offence, but your company does have a certain rep.

> > I have some Fortran subroutines. I have source codes and different
> > version of Fortran compilers available. Could you possibly send me or
> > point me to some examples for calling Fortran subroutines from a root
> > macro? For all Fortran routines that I have, the arguments are double
> > arrays or integer arrays and they do not explicitly return values.
>
> Here is one way:
>
> 1) In your LinkDef.h file put lines like:
>
> #pragma link C++ function fortsub_;

This is problematic if the calling convention isn't the same on all platforms. Doing this, your scripts and linkdef files would have to be done for each and every platform separately. It's better to wrap the function in a C++ function or so (see the attached tar-ball).

> Where "fortsub" is the name of your FORTRAN sub routine. You need the
> trailing underscore.

Just to be clear - that depends on the calling convention used by the Fortran compiler.

> 2) Make a "fortsub.h" file that declares "fortsub_". Arrays of
> doubles or ints are just declared like "double*" or "int*". Say
> fortsub takes both then you'd do:

Erhm, actually, if you want to pass anything to a subroutine, it better be a reference or a pointer on the C/C++ side. Subroutines are allowed to change the value of the passed parameters, and you expect that change to propagate back to the caller (as in pure Fortran). Note, however, that references are enough for normal parameters (arrays, of course, should be pointers).

> // fortsub.h
> extern "C" {
> void fortsub_(double* darray, int* iarray);
> }
>
> 3) Then generate the dictionary code with rootcint
>
> 4) compile and link your .F, the generated dictionary code and any
> other source files you want.
>
> 5) Load lib into root.

See also the script `foo.C' in the attached tar-ball. Note, that I've also shown you have to interface a common block, and how to make sure it's initialised via a small static class.

> It is only the trailing underscore and the need to use
>
> extern "C" { ... }
>
> in the declaration (and knowing how FORTRAN passes arguments) that
> makes using FORTRAN subroutines any different than C++ functions.

Binary calling conventions. The reason for the `extern "C"' is to let the C++ compiler know, that it's shouldn't try to mangle the names in the body of the declaration.

Yours,

-- 
 ___  |  Christian Holm Christensen 
  |_| |  -------------------------------------------------------------
    | |  Address: Sankt Hansgade 23, 1. th.  Phone:  (+45) 35 35 96 91
     _|           DK-2200 Copenhagen N       Cell:   (+45) 24 61 85 91
    _|            Denmark                    Office: (+45) 353  25 404
 ____|   Email:   cholm_at_nbi.dk               Web:    www.nbi.dk/~cholm
 | |

Received on Sat Aug 26 2006 - 12:51:31 MEST

This archive was generated by hypermail 2.2.0 : Mon Jan 01 2007 - 16:32:00 MET