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