java主程序怎样调用子程序_使用Fortran 77子程序作为独立程序,从C调用

本文讨论了如何在Java和C程序中调用Fortran 77编写的子程序。作者在整合过程中遇到了编译错误,如未分类的语句和返回类型不匹配。解决方案涉及到对Fortran源代码的修改,如添加`IMPLICIT NONE`和处理类型匹配问题。最终目标是实现C程序通过传递std::vector向Fortran子程序传递参数并接收计算结果。
摘要由CSDN通过智能技术生成

所以我一直在像瘟疫一样避开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)

相关代码(从文件顶部开始):

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)) .

SECOND ERROR:

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",这样它就不会与函数同名 . 这没有解决错误 . 另外,我将"1"替换为"F",正好在"7 GF(I) = ..."下方并重新编译 . 没有改变 . 我很确定我刚才提到的变化是必要的,但必须有其他事情发生 .

我也读过Data type mismatch in fortran和Function return type mismatch,所以我天真地尝试将"module mycode"添加到顶部,而"end module mycode"添加到文件的底部无济于事 .

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

#include

extern"C"

{

void TP1_(int *mode);

}

int main()

{

TP1_(2);

return 0;

}

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

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

任何和所有指导将不胜感激!!!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值