使用Fortran 77子程序作为独立程序,从C ++调用

时间:2013-08-19 18:28:15

标签: c++ compiler-errors fortran

所以我一直在像瘟疫一样避开Fortran,但最后我的时间到了......我需要参与其他人的Fortran代码(让我们称之为程序A)并用它做两件事:

(1)将其与第三人的Fortran代码合并(让我们称之为程序B),以便B可以调用A

(2)将其与我的C ++代码(程序C)合并,以便C可以调用A

B和C是优化算法,A是基准函数的集合......但在所有可怕的事情发生之前,我必须首先编译我需要的A部分。我需要的所有A子程序都包含在一个文件中。我已根据我上网的信息(例如在代码中添加“IMPLICIT NONE”并使其适合gfortran)进行了改进。但是我有两个顽固的错误和一个警告(我会留下另一个帖子的警告)。

以下是我目前正在编译的方式(通过Makefile):

all:
    gfortran progA.FOR
    g++ -c progC.cpp
    g++ -o Program.out progA.o progC.o
    rm *.o

但第一行未能完成以下错误,

FIRST ERROR:

SUBROUTINE TP1(MODE)
1
Error: Unclassifiable statement at (1)

RELEVANT CODE(从文件顶部开始):

      IMPLICIT NONE  
      INTEGER    NMAX,MMAX,LMAX,MNNMAX,LWA,LIWA,LACTIV,N,NILI,NINL,
     /           NELI,NENL,NEX, MODE              
      PARAMETER (NMAX   = 101, 
     /           MMAX   = 50, 
     /           LMAX   = 50, 
     /           MNNMAX = NMAX + NMAX + MMAX + 2,
     /           LWA    = 2*NMAX*NMAX + 33*NMAX + 10*MMAX + 200,
     /           LIWA   = MMAX + NMAX + 150,
     /           LACTIV = 2*MMAX + 15)  
      LOGICAL    INDEX1,INDEX2

      SUBROUTINE TP1(MODE)      
      COMMON/L1/N,NILI,NINL,NELI,NENL   
      COMMON/L2/X(2)   
      COMMON/L4/GF(2)   
      COMMON/L6/FX      
      COMMON/L9/INDEX1  
      COMMON/L10/INDEX2 
      COMMON/L11/LXL    
      COMMON/L12/LXU    
      COMMON/L13/XL(2)  
      COMMON/L20/LEX,NEX,FEX,XEX(2)     
      REAL*8 X,G,GF,GG,FX,XL,XU,FEX,XEX 
      LOGICAL LXL(2),LXU(2),LEX 
      GOTO (1,2,3,4,4),MODE     
1     N=2       
      NILI=0    
      NINL=0    
      NELI=0    
      NENL=0    
      X(1)=-2.D0
      X(2)=1.D0 
      LXL(1)=.FALSE.    
      LXL(2)=.TRUE.     
      LXU(1)=.FALSE.    
      LXU(2)=.FALSE.    
      XL(2)=-1.5D0      
      LEX=.TRUE.
      NEX=1     
      XEX(1)=1.D0       
      XEX(2)=1.D0       
      FEX=0.D0  
      RETURN    
2     FX=100.D0*(X(2)-X(1)**2)**2+(1.D0-X(1))**2
      RETURN    
3     GF(2)=200.D0*(X(2)-X(1)**2)       
      GF(1)=-2.D0*(X(1)*(GF(2)-1.D0)+1.D0)      
4     RETURN    
      END       

我不明白为什么会出现这个错误,因为有超过300个其他子程序被声明的方式完全相同(例如SUBROUTINE TP2(MODE),...,SUBROUTINE TP300(MODE))。

第二个错误:

HX=TP273A(X)
1
Error: Return type mismatch of function 'tp273a' at (1) (REAL(4)/REAL(8))

相关代码:

      SUBROUTINE TP273(MODE) 
      COMMON/L1/N,NILI,NIML,NELI,NENL 
      COMMON/L2/X 
      COMMON/L4/GF 
      COMMON/L6/FX 
      COMMON/L11/LXL 
      COMMON/L12/LXU 
      COMMON/L20/LEX,NEX,FEX,XEX 
      LOGICAL LEX,LXL(6),LXU(6) 
      REAL*8 X(6),FX,GF(6),FEX,XEX(6),HX,DFLOAT
      GOTO (1,2,3,4,4)MODE 
 1    N=6 
      NILI=0 
      NINL=0 
      NELI=0 
      NENL=0 
      DO 6 I=1,6 
      X(I)=0.D+0 
      XEX(I)=0.1D+1 
      LXL(I)=.FALSE. 
6     LXU(I)=.FALSE. 
      LEX=.TRUE. 
      NEX=1 
      FEX=0.D+0 
      RETURN 
 2    HX=TP273A(X) 
      FX=0.1D+2*HX*(0.1D+1+HX) 
      RETURN 
 3    HX=TP273A(X) 
      DO 7 I=1,6 
 7    GF(I)=0.2D+2*(0.16D+2-DFLOAT(I))*(X(I)-0.1D+1) 
     1       *(0.1D+1+0.2D+1*HX) 
 4    RETURN 
      END       

      REAL*8 FUNCTION TP273A (X) 
      REAL*8 X(6),DFLOAT
      TP273A=0 
      DO 10 I=1,6 
10    TP273A=TP273A+(0.16D+2-DFLOAT(I))*(X(I)-0.1D+1)**2 
      RETURN
      END

在阅读Physics Forums后,我尝试将变量“TP273A”重命名为“TP273Avar”,这样它就不会与函数同名。这没有解决错误。另外,我在“7 GF(I)= ...”下面用“F”替换了“1”并重新编译。没有改变。我很确定我刚才提到的变化是必要的,但必须有其他事情发生。

我还阅读了Data type mismatch in fortranFunction return type mismatch,所以我天真地尝试将“模块mycode”添加到顶部,将“end module mycode”添加到文件底部无效。

在完成所有这些之后,我的目标是使用类似于以下代码从C ++调用这些子例程:

#include <kitchensink>

extern"C"
{
void TP1_(int *mode);
}

int main()
{
    TP1_(2);
    return 0;
}

一旦Fortran代码编译,我想修改子程序,以便C ++可以将std :: vector X传递给TP #_(2,* X,* Y)并获取Y的计算值。我的std: :向量X将替换每个子例程中的COMMON / L2 X,Y将是子例程中计算的FX的值。我使用Mixing Fortran and C作为上述C ++代码的指导。

至于B调用A部分,我希望它就像编译A和B一样简单,并在我需要的地方添加“CALL TP1(MODE)”行。

任何和所有指导都将非常感谢!!!

1 个答案:

答案 0 :(得分:6)

您不能只在编译单元之外的文件中包含语句。这些可以是子程序,函数,模块或程序。在你的情况下,你有一些陈述(第一个是implicit none),只有在它们之后才有子程序TP1的开头。

组织模块中的过程并将公共部分保留在contains部分之前(如果您是Fortran新手,将更多地使用C ++互操作性)或者您必须包含implicit none和其他每个子程序中的其他子程序。如果代码之前有效,你确定你甚至需要这个吗?