RE: Root macro call Fortran subroutines

From: Fine, Valeri <fine_at_bnl.gov>
Date: Mon, 28 Aug 2006 13:18:56 -0400


FYI: C++ compiled with Visual C/C++ can be linked against of the Fortran code compiled by Visual Microsoft/DEC/Compaq Fortran compilers only. The naming rules used by Microsoft compiler doesn't match those from GNU realm (g77 & Co)
All known Fortran/C communication rules were investigated and formalized with CFORTRAN package at the time (see:
http://www-zeus.desy.de/~burow/cfortran/ for details )

Hope this helps.



Best regards
                   Valeri


> -----Original Message-----
> From: owner-roottalk_at_pcroot.cern.ch

[mailto:owner-roottalk_at_pcroot.cern.ch] On
> Behalf Of Weijun Guo
> Sent: Monday, August 28, 2006 9:47 AM
> To: Christian Holm Christensen; Brett Viren
> Cc: RootTalk
> Subject: RE: [ROOT] Root macro call Fortran subroutines
>
> Greetings,
>
> Here comes some feedback and more questions:
>
> After I removed my previous ROOT version for windows Visual Studio and
> installed the gcc version, the Makefile gets to run nicer (and I
changed
> gfortran to g77 in the Makefile.)
>
> However, I still see a lot of error message in the end when it tries
to
> produce the library file:
>
> They are something like the following, many more lines on my screen:
>
> /cygdrive/c/root/lib/libCore.dll.a:misc-inst.cc:(.text+0x626dbc):
first
> defined here
> /cygdrive/c/root/lib/libCint.dll.a:misc-inst.cc:(.text+0x18e4b0):
> multiple definition of `std::num_p
> ut<char, std::ostreambuf_iterator<char, std::char_traits<char> >
> >::_M_pad(char, int, std::ios_base&
> , char*, char const*, int&) const'
> /cygdrive/c/root/lib/libCore.dll.a:misc-inst.cc:(.text+0x60536c):
first
> defined here
> /cygdrive/c/root/lib/libCint.dll.a:misc-inst.cc:(.text+0x18c400):
> multiple definition of `std::num_p
> ut<char, std::ostreambuf_iterator<char, std::char_traits<char> >
> >::_M_group_int(std::basic_string<c
> har, std::char_traits<char>, std::allocator<char> > const&, char,
> std::ios_base&, char*, char*, int&
> ) const'
> /cygdrive/c/root/lib/libCore.dll.a:misc-inst.cc:(.text+0x6032bc):
first
> defined here
> /cygdrive/c/root/lib/libCint.dll.a:misc-inst.cc:(.text+0x1ab380):
> multiple
>
>
> I remembered seeing some discussions in the forum previously, but I
can
> not find the thread now.
>
> Thanks,
>
> Weijun
>
>
>
>
> -----Original Message-----
> From: Christian Holm Christensen [mailto:cholm_at_nbi.dk]
> Sent: Saturday, August 26, 2006 5:51 AM
> To: Brett Viren
> Cc: Weijun Guo; RootTalk
> Subject: Re: [ROOT] Root macro call Fortran subroutines
>
> >
> > 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
> | |
> ----------------------------------------------------------------------
> This e-mail, including any attached files, may contain confidential
and
> privileged information for the sole use of the intended recipient.
Any review,
> use, distribution, or disclosure by others is strictly prohibited. If
you are
> not the intended recipient (or authorized to receive information for
the
> intended recipient), please contact the sender by reply e-mail and
delete all
> copies of this message.
Received on Mon Aug 28 2006 - 19:19:45 MEST

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