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

📄 c_and_f.htm

📁 c/C++跟fortran语言之间的一些转换
💻 HTM
📖 第 1 页 / 共 2 页
字号:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<!-- saved from url=(0063)http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html -->
<HTML><HEAD>
<META http-equiv=Content-Type content="text/html; charset=gb2312">
<META content="MSHTML 6.00.2900.3086" name=GENERATOR></HEAD>
<BODY style="BACKGROUND-COLOR: white"><!-- BEGIN PAGE CONTENT -->[an error 
occurred while processing this directive] 
<H1>Mixing C and Fortran on the SP</H1>
<P>Routines written in Fortran and C/C++ can be mixed in a single program. The 
xlf compiling system assumes that C/C++ routine names are all lower case. 
Following this convention will make compiling and linking easier. </P>
<P>Care must be taken with data types that are passed to the subroutines. Here 
is a table showing corresponding datatypes. </P>
<TABLE class=ntable>
  <TBODY>
  <TR>
    <TH>FORTRAN</TH>
    <TH>C/C++</TH>
    <TH>Bytes</TH></TR>
  <TR>
    <TD><TT>REAL,REAL*4,REAL(KIND=4)</TT></TD>
    <TD><TT>float</TT></TD>
    <TD><TT>4</TT></TD></TR>
  <TR>
    <TD><TT>REAL*8,REAL(KIND=8),DOUBLE PRECISION</TT></TD>
    <TD><TT>double, long double</TT></TD>
    <TD><TT>8</TT></TD></TR>
  <TR>
    <TD><TT>REAL*16,REAL(KIND=16)</TT></TD>
    <TD><TT>long double (with -qlongdouble or -qldbl128)</TT></TD>
    <TD><TT>16</TT></TD></TR>
  <TR>
    <TD><TT>INTEGER, INTEGER*4, INTEGER(KIND=4)</TT></TD>
    <TD><TT>int, long int</TT></TD>
    <TD><TT>4</TT></TD></TR>
  <TR>
    <TD><TT>INTEGER*8, INTEGER(KIND=8)</TT></TD>
    <TD><TT>long long int</TT></TD>
    <TD><TT>8</TT></TD></TR>
  <TR>
    <TD><TT>INTEGER*2</TT></TD>
    <TD><TT>short int</TT></TD>
    <TD><TT>2</TT></TD></TR>
  <TR>
    <TD><TT>COMPLEX, COMPLEX*4</TT></TD>
    <TD><TT>structure of two floats</TT></TD>
    <TD><TT>8</TT></TD></TR>
  <TR>
    <TD><TT>COMPLEX*8</TT></TD>
    <TD><TT>structure of two doubles</TT></TD>
    <TD><TT>16</TT></TD></TR>
  <TR>
    <TD><TT>DOUBLE COMPLEX, COMPLEX*16</TT></TD>
    <TD><TT>structure of two long doubles</TT></TD>
    <TD><TT>32</TT></TD></TR>
  <TR>
    <TD><TT>CHARACTER</TT></TD>
    <TD>See <A 
      href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#characters">Working 
      with characters</A> below.</TD>
    <TD>&nbsp;</TD></TR></TBODY></TABLE>
<P>The subsections of this topic are </P>
<UL>
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#Calling_C_from_Fortran">Calling 
  C from Fortran</A> 
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#Calling_Fortran_from_C">Calling 
  Fortran from C</A> 
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#Cpp">Mixing 
  Fortran and C++</A> 
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#Calling_routines_in_Fortran_modules">Calling 
  routines in Fortran modules</A> 
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#characters">Working 
  with characters</A> 
  <LI><A 
  href="http://www.nersc.gov/nusers/resources/software/ibm/c_and_f.html#case">Using 
  Mixed Case Names</A> </LI></UL>
<P>For further information beyond that found on this page, see The XL Fortran 
User's Guide, chapter 10, <A 
href="http://hpcf.nersc.gov/vendor_docs/ibm/xlf/html/UG74.HTM#HDRILC">"Interlanguage 
Calls."</A> </P>
<H2><A name=Calling_C_from_Fortran>Calling C from Fortran</A> </H2>
<P>As long as you keep in mind how the variable types correspond to each other 
in Fortran and C as shown in the table above, calling a C routine from Fortran 
is straightforward as long as the name of the C routine is all lowercase. </P>
<P>Fortran passes addresses in subroutines calls, so the C routine should accept 
a pointer to the proper data type. </P>
<P>Below is a simple example. First, the Fortran main program: </P>
<DIV class=code><PRE>!FILENAME: f_main.f
!
PROGRAM f_calls_c
        IMPLICIT NONE

        REAL :: p1_x, p1_y, p2_x, p2_y
        EXTERNAL calc_dist

        p1_x = 0.0
        p1_y = 0.0
        p2_x = 3.0
        p2_y = 4.0

        CALL calc_dist(p1_x,p1_y,p2_x,p2_y)

END PROGRAM f_calls_c
</PRE></DIV>
<P>And the C routine: </P>
<DIV class=code><PRE>/* FILENAME: calc_c.c
*/
#include &lt;math.h&gt;
void calc_dist(float *x1, float *y1, float *x2, float *y2)
{
        float dxsq, dysq, distance;

        dxsq = (*x2-*x1)*(*x2-*x1);
        dysq = (*y2-*y1)*(*y2-*y1);

        distance = sqrt( dxsq + dysq );

        printf("The distance between the points is %13.5e\n",
			distance);

}
</PRE></DIV>
<P>Compiling and executing: </P>
<DIV class=terminal><PRE>seaborg% <KBD> cc -c calc_c.c </KBD>
seaborg% <KBD> xlf90  -o f_calls_c f_main.f calc_c.o </KBD>
** f_calls_c   === End of Compilation 1 ===
1501-510  Compilation successful for file f_main.f.
seaborg% <KBD> ./f_calls_c </KBD>
The distance between the points is   5.00000e+00
</PRE></DIV>
<H2><A name=Calling_Fortran_from_C>Calling Fortran from C</A> </H2>
<P>Calling a Fortran routine from C is similar. Here are the same two routines 
as shown above, but with the languages switched for each file. </P>
<DIV class=code><PRE>/* FILENAME: c_main.c
   Shows how to call a FORTRAN routine from C
*/

extern void calc_dist(float*, float*, float*, float*);

void main()
{
        float p1_x,p1_y,p2_x,p2_y;

        p1_x = 0.0;
        p1_y = 0.0;
        p2_x = 3.0;
        p2_y = 4.0;

        calc_dist(&amp;p1_x,&amp;p1_y,&amp;p2_x,&amp;p2_y);
}
</PRE></DIV>
<P></P>
<DIV class=code><PRE>! FILENAME: calc_f.f
!
SUBROUTINE calc_dist(x1,y1,x2,y2)
        IMPLICIT NONE
        REAL :: x1,y1,x2,y2
        REAL :: distance

        distance = SQRT( (x2-x1)**2 + (y2-y1)**2 )

        WRITE(6,1) distance
1       FORMAT("The distance between the points is ", 1pe13.5)

END SUBROUTINE calc_dist
</PRE></DIV>
<P></P>
<DIV class=terminal><PRE>seaborg% <KBD> xlf90 -c calc_f.f </KBD>
** calc_dist   === End of Compilation 1 ===
1501-510  Compilation successful for file calc_f.f.
seaborg% <KBD> cc -o c_calls_f c_main.c calc_f.o -lxlf90 -lm</KBD>
seaborg% <KBD> ./c_calls_f </KBD>
The distance between the points is   5.00000E+00
</PRE></DIV>
<P>Note that we had to explicitly link with <TT>-lxlf90 -lm</TT> when using cc. 
</P>
<H2><A name=Cpp>Mixing Fortran and C++</A> </H2>
<P>In order to mix Fortran and all C++ functions, you must pass the 
interlanguage calls through C "wrapper" functions. This is because the C++ 
compiler "mangles" the names of some C++ functions. C++ functions that are 
declared and used like regular C functions can be called just like C functions, 
however. </P>
<P>In addition, you must use the xlC command to perform the final linkage step. 
</P>
<P>Here's C++ code that performs the same task as does the C function above that 
calculates the distance between points. </P>
<DIV class=code><PRE>/* FILENAME: calc_c++.h 
	This is the C++ routine.
*/
 #include &lt;iostream.h&gt;
 #include &lt;math.h&gt;

template&lt;class T&gt; class calc {

public:

calc() {cout &lt;&lt;"Inside C++ constructor"&lt;&lt;endl;}
~calc() {cout &lt;&lt;"Inside C++ destructor"&lt;&lt;endl;}
 
 void calc_dist(T *x1, T *y1, T *x2, T *y2)
 {
         T dxsq, dysq, distance;

         dxsq = (*x2-*x1)*(*x2-*x1);
         dysq = (*y2-*y1)*(*y2-*y1);

         distance = sqrt( dxsq + dysq );

         cout &lt;&lt;"The distance between the points is "
		&lt;&lt;distance&lt;&lt;" \n"&lt;&lt;endl;

 }
};
</PRE></DIV>
<P>In order to call this routine safely from Fortran, you must "wrap" the 
function with a C-style function, something like this: </P>
<DIV class=code><PRE>/* Filename: calc_cwrapper.C */
#include &lt;stdio.h&gt;
#include "calc_c++.h"

extern "C" void calc_dist(float *x,float *y,float *X,float *Y);

void calc_dist(float *x,float *y,float *X,float *Y) {
        printf("Inside C function, creating C++ object\n");

        calc&lt;float&gt;* c=new calc&lt;float&gt;();
        c-&gt;calc_dist(x,y,X,Y);
        
        printf("Back in C function, will delete C++ object\n");
        delete c;
}
</PRE></DIV>
<P>Compiling and running (using f_main.f): </P>

⌨️ 快捷键说明

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