[comp.lang.c] Calling C from FORTRAN under Unix

packer@amarna.gsfc.nasa.gov (Charles Packer) (05/17/91)

On a Unix system I want to call a C routine from a FORTRAN
program. The linker says the C routine is undefined.  On a VMS
system, the problem doesn't happen. The reason why there is a
problem on a Unix system has something to do with the name of
the C subroutine acquiring a preceding underscore ("_") during
compilation, or some such nonsense. To anyone familiar with this
problem: what is the way around it? 

henry@zoo.toronto.edu (Henry Spencer) (05/17/91)

In article <5343@dftsrv.gsfc.nasa.gov> packer@amarna.gsfc.nasa.gov writes:
>On a Unix system I want to call a C routine from a FORTRAN
>program...

You don't give any indication of what kind of system this is, and that
matters.  The exact procedures you have to follow to call C from FORTRAN,
or vice versa, are *very* system dependent.  You need to go look at the
manuals for your system, probably the FORTRAN manual.
-- 
And the bean-counter replied,           | Henry Spencer @ U of Toronto Zoology
"beans are more important".             |  henry@zoo.toronto.edu  utzoo!henry

oneel@heawk1.gsfc.nasa.gov ( Bruce Oneel ) (05/17/91)

As an example, on sun os 4.1 with f77 1.3.1 (Henry said it was system
dependent) you have to say 

	EXTERNAL ABC,XYZ !$PRAGMA C(ABC,XYZ)

or add an underscore to the c routine name in c.  Needless to say, 30
words doesn't make up for 40 pages of sun manuals.  50 words would,
but not 30 :-)

bruce
--
Bruce O'Neel              oneel@heasfs.gsfc.nasa.gov
NASA/GSFC/STX/Code 664

packer@amarna.gsfc.nasa.gov (Charles Packer) (05/17/91)

In article <1991May17.023941.18053@zoo.toronto.edu>, henry@zoo.toronto.edu (Henry Spencer) writes...
>You don't give any indication of what kind of system this is, and that


That was accidently-on-purpose. The consensus at my site before
I posted was that the answer would apply to Unix generally. Not
the case, as most of the five e-mail respondents pointed out. 

In fact, everybody said that =their= systems' C compiler put an
underscore =following= the routine name, and therefore I should
write the calling Fortran code to CALL subr_.

But we have Ultrix 3.2, whose C compiler PRECEDES the subroutine
name with an underscore. But you can't have the Fortran program
call _subr because the compiler generates a fatal syntax error!

So I went into the Fortran Users Guide for Ultrix 3.2 more
thoroughly than I had yesterday and I find that they document an
extra step to achieve compatibility, something called JBL. In
section 7.4.1.1 they deal with the problem explicitly (though
not so explicitly that they announce it in the table of
contents!).

Thanks anyway!

buckland@ucs.ubc.ca (Tony Buckland) (05/17/91)

In article <5343@dftsrv.gsfc.nasa.gov> packer@amarna.gsfc.nasa.gov writes:
>On a Unix system I want to call a C routine from a FORTRAN
>program. The linker says the C routine is undefined.
>To anyone familiar with this problem: what is the way around it? 

 The technique I have used is to write a little interface routine
 with its entry point having the name the FORTRAN program wants
 to call, and which calls the entry point the C routine provides.
 This was done to call a C library routine.  It works as long as
 the C library routine is FORTRAN-callable in the first place;
 otherwise, the little interface routine has to get bigger, so
 that it can transform between the argument lists provided by
 the FORTRAN program and desired by the C routine.

martelli@cadlab.sublink.ORG (Alex Martelli) (05/19/91)

packer@amarna.gsfc.nasa.gov (Charles Packer) writes:
:On a Unix system I want to call a C routine from a FORTRAN
:program. The linker says the C routine is undefined.  On a VMS
:system, the problem doesn't happen. The reason why there is a
:problem on a Unix system has something to do with the name of
:the C subroutine acquiring a preceding underscore ("_") during
:compilation, or some such nonsense. To anyone familiar with this
:problem: what is the way around it? 
My approach (simplistic compared to others'): C files defining
routines to be called from Fortran include this header file:

#if DECMIPS || IBM6150 || SUN3 || SUN4 || SONY || GREENHILLS
#   define __EXTRA_UNDERLINE        1
#endif
#define FTNLOG(logi)    -(!!(logi))     /* C logical --> FTN logical */
#if __EXTRA_UNDERLINE
#   define FTN(x)       x/**/_          
#   define FTCALL(x)    x/**/_      
#else
#   if  MICROSOFT
#       define FTN(x)   fortran x
#   else
#       define FTN(x)   x               /* to be called from Fortran */
#   endif
#   define FTCALL(x)    x               /* to call a Fortran function */
#endif

then each function is defined, e.g, FTN(name)(arg) float*arg{...etc...}.
If a C routine needs to call "name", it will instead use FTCALL(name)(&x).
The C-compiler script we use on each platform defines an identifiying
constant (of our devising - we choose not to rely on what compilers have
as builtin) as 1 - eg, VMSVAX on you-guess-what, DECMIPS on DECstations,
and so on.  It so happens that currently all of our machines whose Fortran
compilers want a trailing underline accept the old cpp trick of empty
comment for token-pasting; on ANSI C compilers, we'd use the ## pp operator.

There are of course many other macros to facilitate C<->Fortran interface
in a portable way, I just excerpted the portion having to do with trailing
underlines on names.
-- 
Alex Martelli - CAD.LAB s.p.a., v. Stalingrado 53, Bologna, Italia
Email: (work:) martelli@cadlab.sublink.org, (home:) alex@am.sublink.org
Phone: (work:) ++39 (51) 371099, (home:) ++39 (51) 250434; 
Fax: ++39 (51) 366964 (work only), Fidonet: 332/407.314 (home only).

ok@goanna.cs.rmit.oz.au (Richard A. O'Keefe) (05/20/91)

In article <5348@dftsrv.gsfc.nasa.gov>, packer@amarna.gsfc.nasa.gov (Charles Packer) writes:
> In fact, everybody said that =their= systems' C compiler put an
> underscore =following= the routine name, and therefore I should
> write the calling Fortran code to CALL subr_.

That is back to front.  On many UNIX systems, it is the *Fortran*
compiler which adds '_' as a suffix (and either _both_ C and Fortran
add '_' at the beginning (usually BSD) or _neither_ do (usually Sys V)).
So when a C function calls a Fortran 'SUBR' C uses the name 'subr_',
and a C function can be called *from* Fortran only if the C function
name has no capital letters and ends with '_'.  So C would call the
function 'subr_()' and Fortran would 'CALL SUBR'.

However, there are lots of different UNIX Fortran compilers out there,
so it isn't enough to say which hardware and operating system; you have
to say whose Fortran compiler as well.
-- 
There is no such thing as a balanced ecology; ecosystems are chaotic.

packer@amarna.gsfc.nasa.gov (Charles Packer) (05/20/91)

I received 15 e-mail replies to my query, (two since I started
writing this followup) -- thanks to everyone! Almost all of
them, with varying degrees of certainty,  suggested appending
an underscore to the subroutine name in the C source module and
compiling and linking as usual. This included one reply from an
Ultrix 4.1 user. 

But we have Ultrix 4.0, (on a VAXStation) and buried in its
manual is material that tells how to call C from FORTRAN. It
requires an intermediate language they call "JBL." Underscores
are irrelevant. 

To prove that I'm not making this up, below is an excerpt from
the source I used to test the scheme by filling an image array 
in Fortran and passing it to C, which in turn called a display
routine. 




FORTRAN------------------------------

	BYTE IMGDAT(0:511,0:511)
	.
	.
	.
	CALL LTEST(IMGDAT,J)


JBL (in it's entirety)------

LTEST(ref:ref,ref:val);


C-----------------------------------

void ltest_(Img,InVal)
unsigned char Img[512][512];
int InVal;
	{
	.
	.
	.

THE BUILD COMMAND--------------------

	fort aa.for c.jbl csubr.c

[OR, if modules compiled separately,]

	fort aa.o c.jbl csubr.o

jerry@violet.berkeley.edu (Jerry Berkman;217E;24804;;ZA78) (05/21/91)

In article <5360@dftsrv.gsfc.nasa.gov> packer@amarna.gsfc.nasa.gov writes:
>I received 15 e-mail replies to my query, (two since I started
>writing this followup) -- thanks to everyone! Almost all of
>them, with varying degrees of certainty,  suggested appending
>an underscore to the subroutine name in the C source module and
>compiling and linking as usual. This included one reply from an
>Ultrix 4.1 user. 
>
>But we have Ultrix 4.0, (on a VAXStation) and buried in its
>manual is material that tells how to call C from FORTRAN. It
>requires an intermediate language they call "JBL." Underscores
>are irrelevant. 
>
There are two possible Fortran compilers for Ultrix.
The original f77 adds underscores so that "abc" in a Fortran
program becomes "_abc_".  However DEC's VAX Fortran compiler,
fort, converts the letters to uppercase and does not add underscores.
It converts "abc" to "ABC".  Since the C compiler adds an underscore
before each name, you can not link directly to a C procedure from
a Fortran program compiled with DEC's VAX Fortran.

Instead you need to write an interface routine using DEC's
JBL (Jacket Building Language).  The JBL routine is short,
and possibly easy if you know JBL; but a pain if you don't.

In addition to the different names, f77 and fort treat Fortran
character strings differently in argument lists.  For each
character argument, f77 passes two parameters, the address and
length.  I understand fort passes a descriptor which points
to the address and length.  This is probably one reason to use
JBL.

By the way, fort is not the only compiler which doesn't use underscores.
The Cray CFT77 compiler under UNICOS (Cray's version of UNIX) also converts
the name to upper case and does not add any underscores.  But neither
do the Cray C compilers, so you can call the routine "ABC" in C and
link successfully.  I believe the IBM AIX Fortran and C compilers both
just add a period in front of the name, i.e. ".abc".

	- Jerry Berkman, U.C. Berkeley

steve@groucho.ucar.edu (Steve Emmerson) (05/21/91)

In <1991May20.232613.19802@agate.berkeley.edu> jerry@violet.berkeley.edu 
(Jerry Berkman;217E;24804;;ZA78) writes:

>By the way, fort is not the only compiler which doesn't use underscores.
>The Cray CFT77 compiler under UNICOS (Cray's version of UNIX) also converts
>the name to upper case and does not add any underscores.  But neither
>do the Cray C compilers, so you can call the routine "ABC" in C and
>link successfully.  I believe the IBM AIX Fortran and C compilers both
>just add a period in front of the name, i.e. ".abc".

That is correct (at least for the text segment).  Another machine/compiler
combination that doesn't add an underscore is Next/Absoft.

The issue of Fortran-callable C functions can cause considerable problems
when attempting to write portable "jacket" interfaces to C libraries.

Steve Emmerson        steve@unidata.ucar.edu        ...!ncar!unidata!steve

packer@amarna.gsfc.nasa.gov (Charles Packer) (05/21/91)

In article <5360@dftsrv.gsfc.nasa.gov>, packer@amarna.gsfc.nasa.gov (Charles Packer) writes...
>But we have Ultrix 4.0, (on a VAXStation) and buried in its
>manual is material that tells how to call C from FORTRAN. It


Excuse me, I meant to say it's in the =Fortran= manual, which is
version 4.5 according to the title page. Our system manager says
we actually have version 4.8 of the compiler.

wggabb@sdrc.COM (Rob Gabbard) (05/23/91)

From article <5343@dftsrv.gsfc.nasa.gov>, by packer@amarna.gsfc.nasa.gov (Charles Packer):
> On a Unix system I want to call a C routine from a FORTRAN
> program. The linker says the C routine is undefined.  On a VMS
> system, the problem doesn't happen. The reason why there is a
> problem on a Unix system has something to do with the name of
> the C subroutine acquiring a preceding underscore ("_") during
> compilation, or some such nonsense. To anyone familiar with this
> problem: what is the way around it? 

Try declaring your C routine as routinename_
We get around this by having a host dependent include file with a 
special macro in it used in our C function definitions like this:

In the include file (e.g. portable.h):

For an "underscore" machine....
#define IDENTITY(x)		x
#define FORTRAN_CALLABLE(x)	void IDENTITY(x)_

For a "non-underscore" machine....
#define FORTRAN_CALLABLE(x)	void x

Example C funtion definition:

#include "/wherever.../portable.h"

FORTRAN_CALLABLE(routine)(int foo, char *fubar)

The IDENTITY macro is a kludge to get around the fact that x_
doesn't work. The void is there to keep our programmers from designing
any C functions that return values like Fortran functions.  Since there
is no defined standard for this we don't allow it.  In all systems I've
seen returning an int works but you never know.

-- 
The statements above are my own and do not neccesarily reflect the opinion of 
my employer.
-------------------------------------------------------------------------------
Rob Gabbard 				    wggabb@sdrc.sdrc.com
Technical Development Engineer
Structural Dynamics Research Corporation