⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cfortran.html

📁 Cfortran is useful for mixing language programing when you want call some C function in your FORTRAN
💻 HTML
📖 第 1 页 / 共 5 页
字号:
mentions <tt>JBL</tt>, is JBL the only way?

</p><p></p></li><li> VAX VMS C
<p>  The compiler 'easily' exhausts its table space and generates:
<font color="#993300"><pre>%CC-F-BUGCHECK, Compiler bug check during parser phase    .
                Submit an SPR with a problem description.
                At line number 777 in DISK:[DIR]FILE.C;1.
</pre></font>
where the line given, '777', includes a call across C and <i>FORTRAN</i> via
<tt>cfortran.h</tt>, usually with &gt;7 arguments and/or very long argument 
expressions.</p><p>
This SPR can be staved off, with the simple modification to <tt>cfortran.h</tt>, such
that the relevant <tt>CCALLSFSUBn</tt> (or <tt>CCALLSFFUNn</tt> or 
<tt>FCALLSCFUNn</tt>) is not
cascaded up to <tt>CCALLSFSUB14</tt>, and instead has its own copy 
of the contents of 
<tt>CCALLSFSUB14</tt>. 
[If these instructions are not obvious after examining <tt>cfortran.h</tt>
please contact the author.]<br>
[Thanks go to Mark Kyprianou (kyp@stsci.edu) for this solution.]

</p><p></p></li><li> Mips compilers
<p>
  e.g. DECstations and SGI, require applications with a C main() and calls to
GETARG(3F), i.e. <i>FORTRAN</i> routines returning the command line arguments, to use
two macros as shown:
<font color="#993300"><pre>        :
CF_DECLARE_GETARG;              /* This must be external to all routines.     */
        :
main(int argc, char *argv[])
{
        :
CF_SET_GETARG(argc,argv);       /* This must precede any calls to GETARG(3F). */
        :
}
</pre></font>
The macros are null and benign on all other systems. Sun's <tt>GETARG(3F)</tt>
 also
doesn't work with a generic C <tt>main()</tt>
 and perhaps a workaround similar to the
Mips' one exists.

</p><p></p></li><li> Alpha/OSF
<p>Using the DEC <i>FORTRAN</i> and the DEC C compilers of 
DEC OSF/1 [RT] V1.2 (Rev. 10),
<i>FORTRAN</i>, when called from C, has occasional trouble using a routine received as
a dummy argument.

e.g. In the following the <i>FORTRAN</i> routine 'e' will crash when it tries to use
     the C routine 'c' or the <i>FORTRAN</i> routine 'f'.
     The example works on other systems.

<font color="#993300"><pre>C FORTRAN                           /* C */
      integer function f()          #include <stdio.h>
      f = 2                         int f_();
      return                        int e_(int (*u)());
      end
                                    int c(){ return 1;}
      integer function e(u)         int d (int (*u)()) { return u();}
      integer u
      external u                    main()
      e=u()                         {         /* Calls to d  work.  */
      return                        printf("d (c ) returns %d.\n",d (c ));
      end                           printf("d (f_) returns %d.\n",d (f_));
                                              /* Calls to e_ crash. */
                                    printf("e_(c ) returns %d.\n",e_(c ));
                                    printf("e_(f_) returns %d.\n",e_(f_));
                                    }
</stdio.h></pre></font>

Solutions to the problem are welcomed!
A kludge which allows the above example to work correctly, requires an extra
argument to be given when calling the dummy argument function.
i.e. Replacing <tt>'e=u()'</tt> by <tt>'e=u(1)'</tt>
 allows the above example to work.


</p><p></p></li><li> The <i>FORTRAN</i> routines are called using macro expansions, therefore the usual
caveats for expressions in arguments apply. The expressions to the routines may
be evaluated more than once, leading to lower performance and in the worst case
bizarre bugs.

<p></p></li><li> For those who wish to use <tt>cfortran.h</tt> in large applications. 
<a href="http://wwwasd.web.cern.ch/wwwasd/cernlib/cfortran.html#IV">[See Section IV.]</a>
This release is intended to make it easy to get applications up and running. 
This implies that applications are not as efficient as they could be:
<ul>
<p></p><li> The current mechanism is inefficient if a single header file is used to
  describe a large library of <i>FORTRAN</i> functions. Code for a static wrapper fn.
  is generated in each piece of C source code for each <i>FORTRAN</i> function 
  specified with the <tt>CCALLSFFUNn</tt> statement, irrespective of whether or not the
  function is ever called. 
<p></p></li><li> Code for several static utility routines internal to <tt>cfortran.h</tt> is placed 
  into any source code which <tt>#includes cfortran.h</tt>. These routines should
  probably be in a library.
</li></ul>
</li></ul>

<h3>i) Calling <i>FORTRAN</i> routines from C:</h3>

The <i>FORTRAN</i> routines are defined by one of the following two instructions:
<p>
for a SUBROUTINE:
<font color="#993300"><pre>/* PROTOCCALLSFSUBn is optional for C, but mandatory for C++. */
PROTOCCALLSFSUBn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
#define     Routine_name(argname_1,..,argname_n)               \
CCALLSFSUBn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n, \
                         argname_1,..,argname_n) 
</pre></font>

for a FUNCTION:
<font color="#993300"><pre>PROTOCCALLSFFUNn(routine_type,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
#define     Routine_name(argname_1,..,argname_n)               \
CCALLSFFUNn(ROUTINE_NAME,routine_name,argtype_1,...,argtype_n, \
                         argname_1,..,argname_n) 
</pre></font>
Where:
<font color="#993300"></font></p><pre><font color="#993300">'n' = 0-&gt;14 [SUBROUTINE's -&gt;27] (easily expanded in <tt>cfortran.h</tt> to &gt; 14 [27]) is 
    the number of arguments to the routine.
Routine_name = C       name of the routine (IN UPPER CASE LETTERS).[see 2.below]
ROUTINE_NAME = <i>FORTRAN</i> name of the routine (IN UPPER CASE LETTERS).
routine_name = <i>FORTRAN</i> name of the routine (IN lower case LETTERS).
routine_type = the type of argument returned by <i>FORTRAN</i> functions.
             = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING, VOID.
               [Instead of VOID one would usually use CCALLSFSUBn.
                VOID forces a wrapper function to be used.]
argtype_i    = the type of argument passed to the <i>FORTRAN</i> routine and must be
               consistent in the definition and prototyping of the routine s.a.
             = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING.
             For vectors, i.e. 1 dim. arrays use 
             = BYTEV, DOUBLEV, FLOATV, INTV, LOGICALV, LONGV, SHORTV, 
               STRINGV, ZTRINGV.
             For vectors of vectors, i.e. 2 dim. arrays use
             = BYTEVV, DOUBLEVV, FLOATVV, INTVV, LOGICALVV, LONGVV, SHORTVV.
             For n-dim. arrays, 1&lt;=n&lt;=7 [7 is the maximum in <i>FORTRAN</i> 77],
             = BYTEV..nV's..V, DOUBLEV..V, FLOATV..V, INTV..V, LOGICALV..V, 
               LONGV..V, SHORTV..V.
                N.B. Array dimensions and types are checked by the C compiler.
             For routines changing the values of an argument, the keyword is 
                  prepended by a 'P'.
             = PBYTE, PDOUBLE, PFLOAT, PINT, PLOGICAL, PLONG, PSHORT,
               PSTRING, PSTRINGV, PZTRINGV.
             For EXTERNAL procedures passed as arguments use
             = ROUTINE.
             For exceptional arguments which require no massaging to fit the
                  argument passing mechanisms use
             = PVOID.
                The argument is cast and passed as (void *).
                Although PVOID could be used to describe all array arguments on
                most (all?) machines , it shouldn't be because the C compiler
                can no longer check the type and dimension of the array.
argname_i    = any valid unique C tag, but must be consistent in the definition 
               as shown.
</font></pre>

Notes:
<ol>
<p></p><li> <tt>cfortran.h</tt> may be expanded to handle a more argument type. To suppport new
arguments requiring complicated massaging when passed  between <i>FORTRAN</i> and C,
the user will have to understand <tt>cfortran.h</tt> and follow its code and mechanisms.
<p>
To define types requiring little or no massaging when passed between <i>FORTRAN</i> 
and C, the pseudo argument type <tt>SIMPLE</tt> may be used.
For a user defined type called 'newtype', the definitions required are:

<font color="#993300"></font></p><pre><font color="#993300">/* The following 7 lines are required verbatim.
   'newtype' is the name of the new user defined argument type.
*/
#define newtype_cfV(  T,A,B,F)       SIMPLE_cfV(T,A,B,F)
#define newtype_cfSEP(T,  B)         SIMPLE_cfSEP(T,B)
#define newtype_cfINT(N,A,B,X,Y,Z)   SIMPLE_cfINT(N,A,B,X,Y,Z)
#define newtype_cfSTR(N,T,A,B,C,D,E) SIMPLE_cfSTR(N,T,A,B,C,D,E)
#define newtype_cfCC( T,A,B)         SIMPLE_cfCC(T,A,B)
#define newtype_cfAA( T,A,B)         newtype_cfB(T,A) /* Argument B not used. */
#define newtype_cfU(  T,A)           newtype_cfN(T,A)

/* 'parameter_type(A)' is a declaration for 'A' and describes the type of the 
parameter expected by the <i>FORTRAN</i> function.  This type will be used in the
prototype for the function, if  using ANSI C, and to declare the argument used
by the intermediate function if calling a <i>FORTRAN</i> FUNCTION.
Valid 'parameter_type(A)' include: int A
                                   void (*A)()
                                   double A[17]
*/
#define newtype_cfN(  T,A)     parameter_type(A)      /* Argument T not used. */

/* Before any argument of the new type is passed to the <i>FORTRAN</i> routine, it may
be massaged as given by 'massage(A)'.
*/
#define newtype_cfB(  T,A)     massage(A)             /* Argument T not used. */

An example of a simple user defined type is given cfortex.f and cfortest.c.
Two uses of SIMPLE user defined types are [don't show the 7 verbatim #defines]:

/* Pass the address of a structure, using a type called PSTRUCT */
#define PSTRUCT_cfN(  T,A)        void *A
#define PSTRUCT_cfB(  T,A)       (void *) &amp;(A)

/* Pass an integer by value, (not standard F77 ), using a type called INTVAL */
#define INTVAL_cfN(   T,A)      int A
#define INTVAL_cfB(   T,A)         (A)

[If using VAX VMS, surrounding the #defines with "#pragma (no)standard" allows
 the %CC-I-PARAMNOTUSED messages to be avoided.]
</font></pre>

Upgrades to <tt>cfortran.h</tt> try to be, and have been, backwards compatible. This
compatibility cannot be offered to user defined types. <tt>SIMPLE</tt> user defined 
types are less of a risk since they require so little effort in their creation.
If a user defined type is required in more than one C header file of interfaces
to libraries of <i>FORTRAN</i> routines, good programming practice, and ease of code
maintenance, suggests keeping any user defined type within a single file which
is #included as required. To date, changes to the <tt>SIMPLE</tt> macros were introduced
in versions 2.6, 3.0 and 3.2 of <tt>cfortran.h</tt>.

<a name="IIi2"></a>
<p></p></li><li> <tt>Routine_name</tt> is the name of the macro which the C programmer will use in
order to call a <i>FORTRAN</i> routine. In theory <tt>Routine_name</tt> could be any valid and
unique name, but in practice, the name of the <i>FORTRAN</i> routine in UPPER CASE
works everywhere and would seem to be an obvious choice.

<p></p></li><li> <tt>[BYTE|DOUBLE|BYTE|DOUBLE|FLOAT|INT|LOGICAL|LONG|SHORT][V|VV|VVV|...]</tt>
<p>
<tt>cfortran.h</tt> encourages the exact specification of the type and dimension of
array parameters because it allows the C compiler to detect errors in the
arguments when calling the routine.
</p><p>
<tt>cfortran.h</tt> does not strictly require the exact specification since the argument 
is merely the address of the array and is passed on to the calling routine.
Any array parameter could be declared as <tt>PVOID</tt>, but this circumvents
C's compiletime ability to check the correctness of arguments and is therefore
discouraged.
</p><p>
Passing the address of these arguments implies that <tt>PBYTEV</tt>, <tt>PFLOATV</tt>, ... ,
<tt>PDOUBLEVV</tt>, ... don't exist in <tt>cfortran.h</tt>, since by default the routine and the
calling code share the same array, i.e. the same values at the same memory
location.
</p><p>
These comments do NOT apply to arrays of <tt>(P)S/ZTRINGV</tt>. For these parameters,
<tt>cfortran.h</tt> passes a massaged copy of the array to the routine. When the routine
returns, <tt>S/ZTRINGV</tt> ignores the copy, while <tt>PS/ZTRINGV</tt> replaces the calling
code's original array with copy, which may have been modified by the called
routine.


</p><p></p></li><li> <tt>(P)STRING(V)</tt>:
<ul>
<p></p><li><tt>STRING</tt>
<p> If the argument is a fixed length character array, e.g. char ar[8];,
the string is blank, ' ', padded on the right to fill out the array before
being passed to the <i>FORTRAN</i> routine. The useful size of the string is the same
in both languages, e.g. ar[8] is passed as character*7. If the argument is a
pointer, the string cannot be blank padded, so the length is passed as
strlen(argument). On return from the <i>FORTRAN</i> routine, pointer arguments are not
disturbed, but arrays have the terminating '\0' replaced to its original
position. i.e. The padding blanks are never visible to the C code.

</p><p></p></li><li><tt>PSTRING</tt>
<p> The argument is massaged as with STRING before being passed to the
<i>FORTRAN</i> routine. On return, the argument has all trailing blanks removed,
regardless of whether the argument was a pointer or an array.

</p><p></p></li><li><tt>(P)STRINGV</tt>
<p> Passes a 1- or 2-dimensional char array. e.g. <tt>char a[7],b[6][8];</tt>
<tt>STRINGV</tt> may thus also pass a string constant, e.g. <tt>"hiho"</tt>.
<tt>(P)STRINGV</tt> does NOT pass a pointer, e.g. <tt>char *</tt>, to either a 1- or a
2-dimensional array, since it cannot determine the array dimensions.
A pointer can only be passed using <tt>(P)ZTRINGV</tt>.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -