2012-07-30 29 views
0

我正在嘗試用f2py編譯Fortran f90文件,以便在Python中使用。該文件是從另一個文件調用模塊的子例程。該模塊基本上用於分配。我可以在命令窗口中使用'gfortran my_dec.f90'來編譯模塊,但在編譯子例程文件時出現錯誤。這特別困難,因爲我幾乎沒有使用Fortran,而這是別人的代碼。f2py的問題:在子程序中對模塊的未定義引用

這裏是模塊和子程序的部分,因爲它是相當長的,包括它的起點和終點:

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',在subrout中我得到了一大堆關於模塊變量的消息國家統計局:

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 

我一直在努力工作,這一點幾天,包括搜索互聯網的,但無濟於事。有人有主意嗎?這可能是一個相當簡單的問題。謝謝你的幫助。

編輯:如果我將模塊複製並粘貼到與子例程相同的文件中,我已經使用它,但將它作爲單獨文件工作會很好。

回答

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)由編譯器生成,您可以讀取該名稱以識別MODulemy_dec中名爲iaproc的實體。如果my_dec根本沒有定義iaproc,那麼您會收到類似的消息,但這裏不是這種情況。

撇開f2py你(在大多數情況下)只需要確保它是由另一個模塊或子程序或程序used任何模塊編譯首先,鏈接器將做它的魔力(提供的路徑設定等等)。

我不知道你如何告訴f2py在哪裏尋找編譯版本my_dec

我發現現在你已經在編輯中找到了解決方案。我對你爲什麼認爲將子程序的源代碼放在單獨的文件中感到困惑不解。如果你真的想寫Fortran 90子程序也屬於模塊。

+0

感謝您的解釋。我試着編譯my_dec爲'。mod'文件,然後用f2py編譯它,但是這不起作用。我認爲你說的是​​關鍵問題,我們不知道如何告訴f2py你在哪裏尋找編譯版本。 我並不是特別想在獨立文件中使用源代碼和子例程,只是這就是原始代碼的原因,所以我不想改變它。 – LaurieW 2012-07-30 11:14:39

+0

如果您確實無法將子例程的源代碼放入與您可以考慮包含它的模塊源代碼相同的文件中,那麼我的意思是,在模塊的正確位置使用語句「include my_init.f90」文件。但是,這確實需要更改代碼。 – 2012-07-30 12:14:19

相關問題