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

📄 cfortran.html

📁 Cfortran is useful for mixing language programing when you want call some C function in your FORTRAN
💻 HTML
📖 第 1 页 / 共 5 页
字号:
</p><p>N.B. If a C routine receives a character array argument, e.g. <tt>char a[2][3]</tt>,
     such an argument is actually a pointer and my thus not be passed by
     <tt>(P)STRINGV</tt>. Instead <tt>(P)ZTRINGV</tt> must be used.

</p><p></p></li><li><tt>STRINGV</tt>
<p> The elements of the argument are copied into space malloc'd, and
each element is padded with blanks. The useful size of each element is the same
in both languages. Therefore <tt>char bb[6][8];</tt> is equivalent to <tt>character*7 bb(6)</tt>.
On return from the routine the malloc'd space is simply released.

</p><p></p></li><li><tt>PSTRINGV</tt>
<p> Since <i>FORTRAN</i> has no trailing <tt>'\0'</tt>, elements in an array of
strings are contiguous. Therefore each element of the C array is padded with
blanks and strip out C's trailing <tt>'\0'</tt>. After returning from the routine, the
trailing <tt>'\0'</tt> is reinserted and kill the trailing blanks in each element.
</p></li></ul>

<p><b>Summary</b>: <tt>STRING(V)</tt> arguments are blank padded during the call to the <i>FORTRAN</i>
routine, but remain original in the C code. <tt>(P)STRINGV</tt> arguments are blank
padded for the <i>FORTRAN</i> call, and after returning from <i>FORTRAN</i> trailing blanks
are stripped off.

</p><p></p></li><li><tt>(P)ZTRINGV</tt>:

<ul>
<p></p><li> <tt>(P)ZTRINGV</tt> - is identical to <tt>(P)STRINGV</tt>,
except that the dimensions of the array of strings is explicitly specified,
which thus also allows a pointer to be passed.
<tt>(P)ZTRINGV</tt> can thus pass a 1- or 2-dimensional <tt>char</tt> array, e.g. 
<tt>char b[6][8]</tt>,
or it can pass a pointer to such an array, e.g. <tt>char *p;</tt>.
<tt>ZTRINGV</tt> may thus also pass a string constant, e.g. <tt>"hiho"</tt>.
If passing a 1-dimensional array, <tt>routine_name_ELEMS_j</tt> (see below) must be 1.
[Users of <tt>(P)ZTRINGV</tt> should examine <tt>cfortest.c</tt> for examples.]:

<p></p></li><li> <tt>(P)ZTRINGV</tt> must thus be used instead of <tt>(P)STRINGV</tt> whenever 
<tt>sizeof()</tt>
can't be used to determine the dimensions of the array of string or strings.
e.g. when calling <i>FORTRAN</i> from C with a <tt>char *</tt> received by C as an argument.

<p></p></li><li> There is no <tt>(P)ZTRING</tt> type, since <tt>(P)ZTRINGV</tt> can pass a 1-dimensional
array or a pointer to such an array, e.g. <tt>char a[7], *b;</tt>
If passing a 1-dimensional array, <tt>routine_name_ELEMS_j</tt> (see below) must be 1.

<p></p></li><li> To specify the numbers of elements,
<tt>routine_name_ELEMS_j</tt> and <tt>routine_name_ELEMLEN_j</tt> must be defined as shown below
before interfacing the routine with <tt>CCALLSFSUBn</tt>, <tt>PROTOCCALLSFFUNn</tt>, etc.

<font color="#993300"><pre>#define routine_name_ELEMS_j   ZTRINGV_ARGS(k)       
                                 [..ARGS for subroutines, ..ARGF for functions.]
</pre></font>
or

<font color="#993300"><pre>#define routine_name_ELEMS_j   ZTRINGV_NUM(l)
</pre></font>

Where: 
<pre>       routine_name is as above.
       j            [1-n], is the argument being specifying.
       k            [1-n], the value of the k'th argument is the dynamic number
                    of elements for argument j. The k'th argument must be
                    of type BYTE, DOUBLE, FLOAT, INT, LONG or SHORT.
       l            the number of elements for argument j. This must be an
                    integer constant available at compile time.
                    i.e. it is static.
</pre>

<p></p></li><li> Similarly to specify the useful length, [i.e. don't count C's trailing <tt>'\0'</tt>,]
of each element:
<font color="#993300"><pre>#define routine_name_ELEMLEN_j ZTRINGV_ARGS(m)
                                 [..ARGS for subroutines, ..ARGF for functions.]
</pre></font>
or
<font color="#993300"><pre>#define routine_name_ELEMLEN_j ZTRINGV_NUM(q)
</pre></font>
Where: 
<pre>       m            [1-n], as for k but this is the length of each element. 
       q            as for l but this is the length of each element. 
</pre>
</li></ul>


<p></p></li><li> <tt>ROUTINE</tt>
The argument is an <tt>EXTERNAL</tt> procedure.

When C passes a routine to <i>FORTRAN</i>, the language of the function must be
specified as follows:  [The case of <tt>some_*_function</tt> must be given as shown.]
<p>
When C passes a C routine to a <i>FORTRAN</i>: 
<font color="#993300"><pre>    FORTRAN_ROUTINE(arg1, .... ,       
                    C_FUNCTION(SOME_C_FUNCTION,some_c_function),
                    ...., argn);
</pre></font>
and similarly when C passes a <i>FORTRAN</i> routine to <i>FORTRAN</i>:
<font color="#993300"><pre>    FORTRAN_ROUTINE(arg1, .... ,
                    FORTRAN_FUNCTION(SOME_FORT_FUNCTION,some_fort_function),
                    ...., argn);
</pre></font>
If <tt>fcallsc</tt> has been redefined; the same definition of <tt>fcallsc</tt> used when creating
the wrapper for '<tt>some_c_function</tt>' must also be defined when <tt>C_FUNCTION</tt> is used.
<a href="http://wwwasd.web.cern.ch/wwwasd/cernlib/cfortran.html#IIii5">See ii) 5. of this section</a> for when and how to redefine 
<tt>fcallsc</tt>.

<tt>ROUTINE</tt> was introduced with <tt>cfortran.h</tt> version 2.6. Earlier versions of
<tt>cfortran.h</tt> used <tt>PVOID</tt> to pass external procedures as arguments. Using 
<tt>PVOID</tt> for
this purpose is no longer recommended since it won't work 'as is' for
<tt>apolloFortran</tt>, <tt>hpuxFortran800</tt>, 
<tt>AbsoftUNIXFortran</tt>, <tt>AbsoftProFortran</tt>.

</p><p></p></li><li> CRAY only: 
<p>
In a given piece of source code, where FFUNC is any <i>FORTRAN</i> routine,
<tt>FORTRAN_FUNCTION(FFUNC,ffunc)</tt>
disallows a previous 
<tt>#define FFUNC(..) CCALLSFSUBn(FFUNC,ffunc,...)</tt> [ or <tt>CCALLSFFUNn</tt>]
in order to make the <tt>UPPER CASE FFUNC</tt> callable from C.
<tt>#define Ffunc(..) ...</tt> is OK though, as are obviously any other names.
</p></li></ol>

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

Each of the following two statements to export a C routine to <i>FORTRAN</i> create
<i>FORTRAN</i> 'wrappers', written in C, which must be compiled and linked along with
the original C routines and with the <i>FORTRAN</i> calling code.
<p>
<i>FORTRAN</i> callable 'wrappers' may also be created for C macros. i.e. in this
section, the term 'C function' may be replaced by 'C macro'.
</p><p>
for C functions returning void:
<font color="#993300"><pre>FCALLSCSUBn(             Routine_name,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
</pre></font>

for all other C functions:
<font color="#993300"><pre>FCALLSCFUNn(routine_type,Routine_name,ROUTINE_NAME,routine_name,argtype_1,...,argtype_n)
</pre></font>

Where:
'n' = 0-&gt;27 (easily expanded to &gt; 27) stands for the number of arguments to the 
    routine.
<font color="#993300"><pre>Routine_name = the C       name of the routine. [see 9. below]
ROUTINE_NAME = the <i>FORTRAN</i> name of the routine (IN UPPER CASE LETTERS).
routine_name = the <i>FORTRAN</i> name of the routine (IN lower case LETTERS).
routine_type = the type of argument returned by C functions.
             = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING, VOID.
               [Instead of VOID, FCALLSCSUBn is recommended.]
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
             = BYTE, DOUBLE, FLOAT, INT, LOGICAL, LONG, SHORT, STRING.
             For vectors, i.e. 1 dim. arrays use 
             = BYTEV, DOUBLEV, FLOATV, INTV, LOGICALV, LONGV, SHORTV, STRINGV.
             For vectors of vectors, 2 dim. arrays use
             = BYTEVV, DOUBLEVV, FLOATVV, INTVV, LOGICALVV, LONGVV, SHORTVV.
             For n-dim. arrays use
             = BYTEV..nV's..V, DOUBLEV..V, FLOATV..V, INTV..V, LOGICALV..V, 
               LONGV..V, SHORTV..V.
             For routines changing the values of an argument, the keyword is 
                  prepended by a 'P'.
             = PBYTE, PDOUBLE, PFLOAT, PINT, PLOGICAL, PLONG, PSHORT, 
               PSTRING, PNSTRING, PPSTRING, PSTRINGV.
             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 *).
</pre></font>


Notes:
</p><ol>
<p></p><li> For <i>FORTRAN</i> calling C++ routines, C++ does NOT easily allow support for: 
   <tt>STRINGV</tt>.
   <tt>BYTEVV</tt>, <tt>DOUBLEVV</tt>, <tt>FLOATVV</tt>, <tt>INTVV</tt>, <tt>LOGICALVV</tt>, <tt>LONGVV</tt>, <tt>SHORTVV</tt>.
   <tt>BYTEV..V</tt>, <tt>DOUBLEV..V</tt>, <tt>FLOATV..V</tt>, <tt>INTV..V</tt>, <tt>LOGICALV..V</tt>, <tt>LONGV..V</tt>, <tt>SHORTV..V</tt>.
Though there are ways to get around this restriction,
the restriction is not serious since these types are unlikely to be used as
arguments for a C++ routine.

<p></p></li><li> <tt>FCALLSCSUB/FUNn</tt> expect that the routine to be 'wrapped' has been properly
prototyped, or at least declared.


<p></p></li><li> <tt>cfortran.h</tt> may be expanded to handle a new argument type not already among
the above. 


<a name="IIii4"></a>
<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 declaring the routine using <tt>FCALLSCSUB/FUNn</tt>, assuming the
routine to be 'wrapped' has been properly prototyped.
</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)STRINGV</tt>. For these parameters,
<tt>cfortran.h</tt> passes a massaged copy of the array to the routine. When the routine
returns, <tt>STRINGV</tt> ignores the copy, while <tt>PSTRINGV</tt> replaces the calling
code's original array with copy, which may have been modified by the called
routine.


</p><p></p></li><li> <a name="IIii5"></a>
<tt>(P(N))STRING</tt> arguments have any trailing blanks removed before being passed
to C, the same holds true for each element in <tt>(P)STRINGV</tt>. Space is malloc'd in
all cases big enough to hold the original string (elements) as well as C's
terminating <tt>'\0'</tt>. i.e. The useful size of the string (elements) is the same in
both languages. <tt>P(N)STRING(V)</tt> =&gt; the string (elements) will be copied from the
malloc'd space back into the <i>FORTRAN</i> bytes. If one of the two escape mechanisms
mentioned below for PNSTRING has been used, the copying back to <i>FORTRAN</i> is
obviously not relevant.


<p></p></li><li> <tt>(PN)STRING</tt>'s, [NOT <tt>PSTRING</tt>'s nor <tt>(P)STRINGV</tt>'s,] 
behavior may be overridden
in two cases.  In both cases <tt>PNSTRING</tt> and <tt>STRING</tt> behave identically.
<ol>
<p></p><li> If a <tt>(PN)STRING</tt> argument's first 4 bytes are all the <tt>NUL</tt> character,
i.e. <tt>'\0\0\0\0'</tt> the NULL pointer is passed to the C routine.

<p></p></li><li> the <tt>NUL</tt> character, i.e. C strings' terminating 
<tt>'\0'</tt>, the address of the string
is simply passed to the C routine. i.e. The argument is treated in this case as
it would be with <tt>PPSTRING</tt>, to which we refer the reader for more detail.
</li></ol>
<p>
Mechanism 1. overrides 2. . Therefore, to use this mechanism to pass the <tt>NULL</tt>
string, <tt>""</tt>, to C, the first character of the string must obviously be the <tt>NUL</tt>
character, but of the first 4 characters in the string, at least one must not
be <tt>HEX-00</tt>.

</p><p>Example:
<font color="#993300"></font></p><pre>
<font color="#993300"><b>C FORTRAN                                               /* C */</b>
      character*40 str                                  #include "cfortran.h"
C Set up a NULL as :                                    void cs(char *s) {if (s) printf("%s.\n",s);}
C    i)  4 NUL characters.                              FCALLSCSUB1(cs,CS,cs,STRING)
C    ii) NULL pointer.
      character*4 NULL        
      NULL = CHAR(0)//CHAR(0)//CHAR(0)//CHAR(0)

      data str/'just some string'/

C Passing the NULL pointer to cs.
      call cs(NULL)
C Passing a copy of 'str' to cs.
      call cs(str)
C Passing address of 'str' to cs. Trailing blanks NOT killed.
      str(40:) = NULL
      call cs(str)
      end
</font></pre>

Strings passed from <i>FOR

⌨️ 快捷键说明

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