简体   繁体   English

在C ++中将fortran 66/77编译为八度的未定义符号?

[英]undefined symbol compiling fortran 66/77 in c++ to octave?

I keep receiving the "undefined symbol: ising3d_" error when I execute the ising3d.f inside of the ising3d_fort2oct.cc. 当我在ising3d_fort2oct.cc内部执行ising3d.f时,我不断收到“未定义符号:ising3d_”错误。 Can anyone provide suggestions on what I could to change either ising3d.f or ising3d_fort2oct.cc to fix this problem? 谁能提供关于我可以更改ising3d.f或ising3d_fort2oct.cc来解决此问题的建议?

Octave Terminal Commands : 八度终端命令:

octave:12> system("gfortran ising3d.f -o ising3d")
ans = 0
octave:13> mkoctfile ising3d_fort2oct.cc
octave:14> ising3d_fort2oct
error: /home/b/Desktop/Umaine_Classes/CHY_573/3disingmodelf/ising3d_fort2oct.oct: failed to load: /home/b/Desktop/Umaine_Classes/CHY_573/3disingmodelf/ising3d_fort2oct.oct: undefined symbol: ising3d_
octave:14> 

ising3d_fort2oct.cc : Dynamically Linked C++ Function calling fortran subroutine ising3d.f : ising3d_fort2oct.cc:动态链接的C ++函数,调用fortran子例程ising3d.f:

#include <octave/oct.h>
#include <octave/f77-fcn.h>
extern "C" void F77_FUNC (ising3d,ISING3D)();
DEFUN_DLD (ising3d_fort2oct, args , ,"work in progress")
    {
        octave_value_list retval;
        F77_FUNC(ising3d,ISING3D)();
        return retval;
    }

ising3d.f : really old fortran subroutine : ising3d.f:确实很老的fortran子例程:

          SUBROUTINE ising3d()
C         3D ISING MODEL
C         Critical temperature TC = 4.5116=1/.22165
          DIMENSION IS(10,10,10), EX(13)
          REAL *8 R(1)
          DATA IS/1000*1/
          ITMAX=5000
          ISTART=4000
          L=10
          NR=1
          ISEED=768521034
          M=L*L*L
          DO 1000 K=1,24
          TR=0.05+(K-1)*.05
          T=TR/.221655
          MR=0.
          DO 3 I=1, 13, 2
3         EX(I)=EXP(-2*(I-7.)/T)
          DO 2 ITIME=1,ITMAX
          DO 1 K1=1,L
          K1P1=K1+1
          K1M1=K1-1
          IF(K1.EQ.1) K1M1=L
          IF(K1.EQ.L) K1P1=1
          DO 1 K2=1,L
          K2P1=K2+1
          K2M1=K2-1
          IF(K2.EQ.1) K2M1=L
          IF(K2.EQ.L) K2P1=1
          DO 1 K3=1,L
          K3P1=K3+1
          K3M1=K3-1
          IF(K3.EQ.1) K3M1=L
          IF(K3.EQ.L) K3P1=1
        IEN=7+IS(K3,K2,K1)*(IS(K3M1,K2,K1)+IS(K3P1,K2,K1)+IS(K3,K2M1,K1)
     &  +IS(K3,K2P1,K1)+IS(K3,K2,K1M1)+IS(K3,K2,K1P1))
          CALL GGUBS(ISEED,NR,R)
          IF(EX(IEN).LT.R(1)) GOTO 1
          IS(K3,K2,K1)=-IS(K3,K2,K1)
          M=M+2*IS(K3,K2,K1)
C          WRITE(*,*) M,ITIME
1         CONTINUE
          IF (ITIME.GT.ISTART) MR=MR+M
2         CONTINUE
          WRITE(*,*) FLOAT(MR)/1000./FLOAT((ITMAX-ISTART)),TR
          WRITE(1,*) FLOAT(MR)/1000./FLOAT((ITMAX-ISTART)),TR
1000      CONTINUE
          STOP
          END
          RETURN
          END

        SUBROUTINE GGUBS(ISEED,NR,R)
        IMPLICIT REAL *8(A-H,O-Z)
        DIMENSION R(NR)
        DATA D2P31M/2147483647.D0/
        DATA D2P31/2147483648.D0/
        DO 7 I=1,NR
        ISEED=MOD(16807.D0*ISEED, D2P31M)
        R(I)=ISEED/D2P31
    7   CONTINUE
        RETURN
        END

The problem is not in the code but in the way you are compiling and linking the oct-file to be called from Octave. 问题不在于代码,而在于您编译和链接要从Octave调用的oct文件的方式。 When you built ising3d_fort2oct , you did not instruct it to link with or how to find the ising3d Fortran function. 构建ising3d_fort2oct ,没有指示它链接或如何找到ising3d Fortran函数。

You can link these two source files together in one of two ways. 您可以通过以下两种方式之一将这两个源文件链接在一起。 You can compile each individually and then link the resulting object files together, or you can call mkoctfile once with both source files and let it do everything for you. 您可以单独编译每个文件,然后将生成的目标文件链接在一起,或者可以对两个源文件调用一次mkoctfile ,然后让它为您做所有事情。

To build the oct-file from both sources with one command, do 要使用一个命令从两个源构建oct文件,请执行

octave:1> mkoctfile ising3d_fort2oct.cc ising3d.f

in the Octave shell, where mkoctfile is told about the second source file to compile and link together with the first. 在Octave Shell中,告诉mkoctfile第二个要编译的源文件并与第一个源文件链接在一起。

To build the Fortran subroutine separately, as you were attempting to do, and then link it later with the oct-file wrapper, you can instead do 如要尝试分别构建Fortran子例程,然后再将其与oct-file包装器链接,则可以执行以下操作:

octave:1> system ("gfortran -c ising3d.f -o ising3d.o");
octave:2> mkoctfile ising3d_fort2oct.cc ising3d.o

Note that you still need to link the oct-file with the object file explicitly. 请注意,您仍然需要将oct文件与目标文件明确链接。 Otherwise the oct-file will be compiled assuming that the function is provided by Octave itself or by a system library, and that is why you get an undefined symbol error. 否则,假定函数由Octave本身或系统库提供,则将编译oct文件,这就是为什么会出现未定义的符号错误的原因。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM