📄 cfortran.html
字号:
By changing the SELECTion <tt>ifdef</tt> of <tt>cfortest.c</tt> and recompiling one can try out
a few dozen different few-line examples.
<p>
The benefits of using <tt>cfortran.h</tt> include:
</p><ol>
<p></p><li> Machine/OS/compiler independent mixing of C and <i>FORTRAN</i>.
<p></p></li><li> Identical (within syntax) calls across languages, e.g.
<font color="#993300"><pre><b>FORTRAN:</b>
CALL HBOOK1(1,'pT spectrum of pi+',100,0.,5.,0.)
<b>C:</b>
HBOOK1(1,"pT spectrum of pi+",100,0.,5.,0.);
</pre></font>
<p></p></li><li> Each routine need only be set up once in its lifetime. e.g.
Setting up a FORTRAN routine to be called by C.
ID,...,VMX are merely the names of arguments.
These tags must be unique w.r.t. each other but are otherwise arbitrary.
<font color="#993300"><pre>PROTOCCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT)
#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \
CCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT, \
ID,CHTITLE,NX,XMI,XMA,VMX)
</pre></font>
<p></p></li><li> Source code is NOT required for the C routines exported to <i>FORTRAN</i>, nor for
the <i>FORTRAN</i> routines imported to C. In fact, routines are most easily
prototyped using the information in the routines' documentation.
<p></p></li><li> Routines, and the code calling them, can be coded naturally in the language
of choice. C routines may be coded with the natural assumption of being
called only by C code. <tt>cfortran.h</tt> does all the required work for <i>FORTRAN</i>
code to call C routines. Similarly it also does all the work required for C
to call <i>FORTRAN</i> routines. Therefore:
<ul>
<li> C programmers need not embed <i>FORTRAN</i> argument passing mechanisms into
their code.
</li><li> <i>FORTRAN</i> code need not be converted into C code. i.e. The honed and
time-honored <i>FORTRAN</i> routines are called by C.
</li></ul>
<p></p></li><li> <tt>cfortran.h</tt> is a single ~1700 line C include file; portable to most
remaining, if not all, platforms.
<p></p></li><li> <tt>STRINGS</tt> and <tt>VECTORS</tt> of
<tt>STRINGS</tt> along with the usual simple arguments to
routines are supported as are functions returning
<tt>STRINGS</tt> or numbers. Arrays
of pointers to strings and values of structures as C arguments,
will soon be
implemented.
After learning the machinery of <tt>cfortran.h</tt>, users can expand
it to create custom types of arguments. [This requires no modification to
<tt>cfortran.h</tt>, all the preprocessor
directives required to implement the
custom types can be defined outside <tt>cfortran.h</tt>]
<p></p></li><li> <tt>cfortran.h</tt> requires each routine to be exported to be explicitly set up.
While is usually only be done once in a header file it would be best if
applications were required to do no work at all in order to cross languages.
<tt>cfortran.h</tt>'s simple syntax could be a convenient back-end for a program
which would export <i>FORTRAN</i> or C routines directly from the source code.
</li></ol>
<h3>Example 1 </h3>
<tt>cfortran.h</tt> has been used to make the C header file <tt>hbook.h</tt>,
which then gives any C programmer, e.g. <tt>example.c</tt>, full and
completely transparent access to <b>CERN</b>'s <b>HBOOK</b> library of routines.
Each <b>HBOOK</b> routine required about 3 lines of simple code in
<tt>hbook.h</tt>. The example also demonstrates how <i>FORTRAN</i> common blocks
are defined and used.
<font color="#993300"><pre>/* hbook.h */
#include "cfortran.h"
:
PROTOCCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT)
#define HBOOK1(ID,CHTITLE,NX,XMI,XMA,VMX) \
CCALLSFSUB6(HBOOK1,hbook1,INT,STRING,INT,FLOAT,FLOAT,FLOAT, \
ID,CHTITLE,NX,XMI,XMA,VMX)
:
/* end hbook.h */
/* example.c */
#include "hbook.h"
:
typedef struct {
int lines;
int status[SIZE];
float p[SIZE]; /* momentum */
} FAKE_DEF;
#define FAKE COMMON_BLOCK(FAKE,fake)
COMMON_BLOCK_DEF(FAKE_DEF,FAKE);
:
main ()
{
:
HBOOK1(1,"pT spectrum of pi+",100,0.,5.,0.);
/* c.f. the call in FORTRAN:
CALL HBOOK1(1,'pT spectrum of pi+',100,0.,5.,0.)
*/
:
FAKE.p[7]=1.0;
:
}
</pre></font>
<b>N.B.</b>
<ol>
<li> The routine is language independent.
</li><li> <tt>hbook.h</tt> is machine independent.
</li><li> Applications using routines via <tt>cfortran.h</tt> are machine independent.
</li></ol>
<h3>Example 2</h3> Many VMS System calls are most easily called from <i>FORTRAN</i>, but
<tt>cfortran.h</tt> now gives that ease in C.
<font color="#993300"></font><pre><font color="#993300">#include "cfortran.h"
PROTOCCALLSFSUB3(LIB$SPAWN,lib$spawn,STRING,STRING,STRING)
#define LIB$SPAWN(command,input_file,output_file) \
CCALLSFSUB3(LIB$SPAWN,lib$spawn,STRING,STRING,STRING, \
command,input_file,output_file)
main ()
{
LIB$SPAWN("set term/width=132","","");
}
</font></pre>
Obviously the <tt>cfortran.h</tt> command above could be put into a header file along
with the description of the other system calls, but as this example shows, it's
not much hassle to set up <tt>cfortran.h</tt> for even a single call.
<h3>Example 3</h3> <tt>cfortran.h</tt> and the source cstring.c create the cstring.obj library
which gives <i>FORTRAN</i> access to all the functions in C's system
library described by the system's C header file <tt>string.h</tt>.
<font color="#993300"><pre>C EXAMPLE.FOR
PROGRAM EXAMPLE
DIMENSION I(20), J(30)
:
CALL MEMCPY(I,J,7)
:
END
/* cstring.c */
#include <string.h> /* string.h prototypes memcpy() */
#include "cfortran.h"
:
FCALLSCSUB3(memcpy,MEMCPY,memcpy,PVOID,PVOID,INT)
:
</string.h></pre></font>
The simplicity exhibited in the above example exists for many but not all
machines.
<a href="http://wwwasd.web.cern.ch/wwwasd/cernlib/cfortran.html#IIii4">Note 4. of Section II ii)</a> details the limitations and describes tools
which try to maintain the best possible interface when <i>FORTRAN</i> calls C
routines.
<h2>II) Using cfortran.h</h2>
The user is asked to look at the source files <tt>cfortest.c</tt> and
<tt>cfortex.f</tt>
for clarification by example.
<p>
</p><h3>o) Notes:</h3>
<ul>
<p></p><li> Specifying the <i>FORTRAN</i> compiler
<p>
<tt>cfortran.h</tt> generates interfaces for the default i
<i>FORTRAN</i> compiler. The default can be overridden by defining with
one of the follwoing methods,
</p><ul>
<p></p><li> in the code, e.g.: <tt>#define NAGf90Fortran</tt>
<p></p></li><li> in the compile directive, e.g.: <tt>unix> cc -DNAGf90Fortran</tt>
</li></ul>
one of the following before including <tt>cfortran.h</tt>:
<font color="#993300"><pre> NAGf90Fortran f2cFortran hpuxFortran apolloFortran sunFortran
IBMR2Fortran CRAYFortran mipsFortran DECFortran vmsFortran
CONVEXFortran PowerStationFortran AbsoftUNIXFortran
SXFortran pgiFortran AbsoftProFortran
</pre></font>
This also allows crosscompilation.
<p>
If wanted, <tt>NAGf90Fortran</tt>, <tt>f2cFortran</tt>, <tt>DECFortran</tt>, <tt>AbsoftUNIXFortran</tt>,
<tt>AbsoftProFortran</tt> and <tt>pgiFortran</tt> must be requested by the user.
</p><p></p></li><li><tt>/**/</tt>
<p>
<tt>cfortran.h</tt> (ab)uses the comment kludge <tt>/**/</tt> when the
ANSI C preprocessor
catenation operator <tt>##</tt> doesn't exist.
In at least MIPS C, this kludge is
sensitive to blanks surrounding arguments to macros.
Therefore, for applications using non-ANSI C compilers, the
<tt>argtype_i</tt>,
<tt>routine_name</tt>,
<tt>routine_type</tt>
and
<tt>common_block_name arguments</tt> to the
<tt>PROTOCCALLSFFUNn</tt>, <tt>CCALLSFSUB/FUNn</tt>, <tt>FCALLSCSUB/FUNn</tt> and <tt>COMMON_BLOCK</tt> macros
<b> must not</b> be followed by any white space characters such as
blanks, tabs or newlines.
</p><p></p></li><li> <tt>LOGICAL</tt>
<p>
<i>FORTRAN</i> <tt>LOGICAL</tt> values of .TRUE. and .FALSE. do not agree with the C
representation of TRUE and FALSE on all machines. <tt>cfortran.h</tt> does the
conversion for <tt>LOGICAL</tt> and PLOGICAL arguments and for functions returning
<tt>LOGICAL</tt>. Users must convert arrays of <tt>LOGICAL</tt>s from C to <i>FORTRAN</i> with the
C2FLOGICALV(array_name, elements_in_array); macro. Similarly, arrays of <tt>LOGICAL</tt>
values may be converted from the <i>FORTRAN</i> into C representation by using
F2CLOGICALV(array_name, elements_in_array);
</p><p>
When C passes or returns <tt>LOGICAL</tt> values to <i>FORTRAN</i>, by default <tt>cfortran.h</tt>
only makes the minimal changes required to the value. [e.g. Set/Unset the
single relevant bit or do nothing for <i>FORTRAN</i> compilers which use 0 as FALSE
and treat all other values as TRUE.] Therefore <tt>cfortran.h</tt> will pass <tt>LOGICAL</tt>s
to <i>FORTRAN</i> which do not have an identical representation to .TRUE. or .FALSE.
This is fine except for abuses of <i>FORTRAN</i>/77 in the style of:
<font color="#993300"></font></p><pre><font color="#993300"> logical l
if (l .eq. .TRUE.) ! (1)
</font></pre>
instead of the correct:
<font color="#993300"><pre> if (l .eqv. .TRUE.) ! (2)
</pre></font>
or:
<font color="#993300"><pre> if (l) ! (3)
</pre></font>
For <i>FORTRAN</i> code which treats <tt>LOGICAL</tt>s from C in the method of (1),
<tt>LOGICAL_STRICT</tt> must be defined before
including <tt>cfortran.h</tt>, either in the
code, <tt>"#define LOGICAL_STRICT"</tt>, or compile with
<tt>"cc -DLOGICAL_STRICT"</tt>.
There is no reason to use <tt>LOGICAL_STRICT</tt> for <i>FORTRAN</i>
code which does not do (1).
At least the IBM's <tt>xlf</tt> and the Apollo's <tt>f77</tt>
do not even allow code along the
lines of (1).
<p>
DECstations' <tt>DECFortran</tt> and MIPS <i>FORTRAN</i> compilers use
different internal
representations for <tt>LOGICAL</tt> values.
[Both compilers are usually called <tt>f77</tt>,
although when both are installed on a single machine the MIPS' one is usually
renamed. (e.g. <tt>f77</tt>2.1 for version 2.10.)] <tt>cc</tt> doesn't know
which <i>FORTRAN</i>
compiler is present, so <tt>cfortran.h</tt> assumes MIPS <tt>f77</tt>.
To use <tt>cc</tt> with DECFortran
define the preprocessor constant 'DECFortran'.
e.g.
<font color="#993300"><pre> <b>i) </b> cc -DDECFortran -c the_code.c
</pre></font>
or
<font color="#993300"></font></p><pre><font color="#993300"> <b>ii)</b> #define DECFortran /* in the C code or add to <tt>cfortran.h</tt>. */
</font></pre>
MIPS <tt>f77</tt> [SGI and DECstations], <tt>f2c</tt>, and <tt>f77</tt> on
VAX Ultrix treat
<tt>.eqv./.neqv.</tt> as <tt>.eq./.ne.</tt>. Therefore,
for these compilers, <tt>LOGICAL_STRICT</tt> is
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -