0

我正在尝试用 f2py 编译一个 Fortran f90 文件,以便在 Python 中使用。该文件是从另一个文件调用模块的子程序。该模块基本上是用于分配的。我可以在命令窗口中使用“gfortran my_dec.f90”来编译模块,但是在尝试编译子例程文件时出现错误。这尤其困难,因为我几乎没有使用过 Fortran,而且这是别人的代码。

这是模块和子程序的一部分,因为它很长,包括它的开始和结束:

 module my_dec

    integer ndir, nfreq
    integer ihmax,ier
    integer nk,nth,nspec


    real hspmin
    real wsmult
    real wscut

    logical flcomb, flc 

    parameter(ndir=24)
    parameter(nfreq=23)

    parameter(nk=nfreq)
    parameter(nth=ndir)
    parameter(nspec=nk*nth)

    REAL DTH, SIG(0:nk+1), DSII(0:nk+1), DSIP(0:nk+1)
    REAL ECOS(nspec+nth), ESIN(nspec+nth), XFR 
    REAL FACHFE, TH(nth), FTE

    REAL ES2(nspec+NTH),EC2(nspec+NTH),ESC(nspec+NTH)
    REAL DDEN(NK),DDEN2(nspec)
    REAL SIG2(nspec)

    INTEGER IAPROC, NAPERR, NDSE, NDST

    INTEGER year, TIME 

    real pcg ! percentage either side of peakfor gamma estimate

    data pcg/0.3/ 

end module my_dec

子程序:

子程序 my_init

use my_dec
use constants

iaproc=1
naperr=1
ndset=1
ndst=1

IHM    = 100
HSPM   = 0.05
WSM    = 1.7
WSC    = 0.333
FLC    = .true.


IHMAX  = MAX ( 50, IHM )
HSPMIN = MAX ( 0.0001 , HSPM )
WSMULT = MAX ( 1. , WSM )
WSCUT  = MIN ( 1.0001 , MAX ( 0. , WSC ) )
FLCOMB = FLC

...      

    return

    end

当我尝试使用“f2py -c my_init.f90 -m my_init_m”编译子例程文件“my_init.f90”时,我在子例程中收到一大堆消息,关于从模块中引用变量:

c:\users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o:my_init.f90:(.text+0
xb): undefined reference to `__my_dec_MOD_iaproc'
c:\users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o:my_init.f90:(.text+0
x15): undefined reference to `__my_dec_MOD_naperr'
c:\users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o:my_init.f90:(.text+0
x26): undefined reference to `__my_dec_MOD_ndst'
c:\users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o:my_init.f90:(.text+0
x4f): undefined reference to `__my_dec_MOD_flc'

然后是错误,对我来说并没有太多启示:

collect2: ld returned 1 exit status
error: Command "C:\Python27\Scripts\gfortran.exe -Wall -Wall -shared c:\users\lw
l\appdata\local\temp\tmptlve6z\Release\users\lwl\appdata\local\temp\tmptlve6z\sr
c.win-amd64-2.7\my_init_mmodule.o c:\users\lwl\appdata\local\temp\tmptlve6z\Rele
ase\users\lwl\appdata\local\temp\tmptlve6z\src.win-amd64-2.7\fortranobject.o c:\
users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o -Lc:\python27\egg-info\
mingw\usr\lib\gcc\x86_64-w64-mingw32\4.5.2 -LC:\Python27\libs -LC:\Python27\PCbu
ild\amd64 -lpython27 -lgfortran -o .\my_init_m.pyd" failed with exit status 1

这几天我一直在尝试解决这个问题,包括搜索互联网,但无济于事。有人有想法么?这可能是一个非常简单的问题。谢谢你的帮助。

编辑:如果我将模块复制并粘贴到与子例程相同的文件中,我就可以使用它了,但是让它作为单独的文件使用它们会很好。

4

1 回答 1

2

对不起,如果这个解释涵盖了你已经知道的基础,但你确实写了你几乎不知道 Fortran。

您的例程my_init使用名为my_dec(和一个名为constants)的模块。这就是use声明所说的。错误消息如

c:\users\lwl\appdata\local\temp\tmptlve6z\Release\my_init.o:my_init.f90:(.text+0
xb): undefined reference to `__my_dec_MOD_iaproc'

如果您尝试在不提供链接到my_init的编译版本的情况下进行编译,我希望看到的内容。my_dec诸如由编译器生成的名称,__my_dec_MOD_iaproc您可以将该名称读取为标识iaproc. 如果根本没有定义,MODule my_dec您会收到类似的消息,但这里不是这种情况。my_deciaproc

撇开f2py您(在大多数情况下)不谈,只需确保used首先编译另一个模块或子程序或程序的任何模块,链接器就会发挥它的魔力(只要设置了路径等等)。

我不知道你怎么知道f2py在哪里寻找my_dec.

我看到您现在在编辑中找到了解决方案。我很困惑为什么您认为将子例程的源代码放在单独的文件中会很好。如果你真的想写 Fortran 90 子程序也属于模块。

于 2012-07-30T10:23:21.230 回答