1

我必须在 fortran 程序中导入一个 MAT 文件。我遵循了示例文件,但在链接时遇到了一些问题。编译进行得很好。

最小代码:

#include "fintrf.h"

PROGRAM main 

USE ssa
USE dmotifs
USE param

IMPLICIT NONE

! MAT-FILE Declarations !

INTEGER matOpen, matGetDir 
INTEGER matGetVariableInfo
INTEGER mp, dir, adir(100), pa
INTEGER mxGetM, mxGetN, matClose
INTEGER ndir, i, clstat
CHARACTER*32 names(100) 

!===========================!

if(all(fnames(:)%fn .NE. argfun)) then
    write(*,*) "No such motif: ",argfun
    write(*,*) "Input format-> main <motifname>"
    stop
else

    fin=fchton(argfun)  
    y0=nM2m*analys(p,argfun)

    ! ==> OPEN MAT-file <== !

    mp=matOpen('./PRMS_lxr_29Apr15.mat','r')

    if (mp .eq. 0) then
         write(6,*) "Can't open MAT-file"
         stop
    end if

    dir = matgetdir(mp, ndir)

      if (dir .eq. 0) then
         write(6,*) "Can't read MAT-file-directory."
         stop
    endif

    call mxCopyPtrToPtrArray(dir, adir, ndir)

    do 20 i=1,ndir
         call mxCopyPtrToCharacter(adir(i), names(i), 32)
 20 continue

    write(6,*) 'Directory of Mat-file:'

    do 30 i=1,ndir
        write(6,*) names(i)
 30 continue

    write(6,*) 'Getting Header info from first array.'
    pa = matGetVariableInfo(mp, names(1))
    write(6,*) 'Retrieved ', names(1)
    write(6,*) '  With size ', mxGetM(pa), '-by-', mxGetN(pa)
    call mxDestroyArray(pa)

    clstat=matClose(mp)

end if
END PROGRAM main

我正在使用 gfortran 4.8.3 使用默认命令进行编译+链接:

gfortran main.f90 dmotifs.o param.o ssa.o -o main

当我不包含时,这段代码编译得很好(没有链接)#include "finitrf.h",否则编译器会说

Warning: main.f90:1: Illegal preprocessor directive

我尝试重命名finitrf.h为,finitrf.f90但没有任何区别。尽管如此,在链接过程中我收到了这些错误:

main.f90:(.text+0x3ea): undefined reference to `matopen_'
main.f90:(.text+0x487): undefined reference to `matgetdir_'
main.f90:(.text+0x52b): undefined reference to `mxcopyptrtoptrarray_'
main.f90:(.text+0x583): undefined reference to `mxcopyptrtocharacter_'
main.f90:(.text+0x71b): undefined reference to `matgetvariableinfo_'
main.f90:(.text+0x804): undefined reference to `mxgetm_'
main.f90:(.text+0x855): undefined reference to `mxgetn_'
main.f90:(.text+0x89c): undefined reference to `mxdestroyarray_'
main.f90:(.text+0x8b0): undefined reference to `matclose_'
collect2: error: ld returned 1 exit status

我需要生成文件或在编译命令中添加其他参数吗?

编辑:

我添加了-cpp选项,这消除了问题Illegal preprocessor directive

现在,当我使用 matlab 外部组件(finitf.h 所在的位置)的路径进行编译时,我仍然遇到同样的错误。

gfortran main.f90 dmotifs.o param.o ssa.o -I/usr/local/matlab2008a/extern/include -L/usr/local/matlab2008a/extern/lib -cpp -o main

如果我提供/usr/local/matlab2008a/bin/glnxa64包含其他 matlab 库的库路径,包括libmat.so,我仍然会遇到相同的错误。

4

2 回答 2

1

对于小写文件扩展名*.f90*.f预处理器通常被停用。要启用此功能,请将(主)文件重命名为具有大写扩展名*.F90*.F,或提供相应的命令行选项(-cppfor gfortran-fppfor ifort)。

假设缺少的子例程/函数实际上是在中声明的fintrf.h,这应该可以解决您的问题。

您还应该告诉编译器链接到包含 Matlab 函数的库。

于 2015-05-12T08:45:32.090 回答
0

正如 Alexander Vogt 所指出的,编译器需要-cpp预处理器的选项来识别头文件,而不是将其视为非法。

链接要求finitrf.h通常位于 中,<matlabroot>/extern/include而基本库位于<matlabroot>/bin/<arch>/.

但是仅仅指定这一点是行不通的,确切的 matlab 库的规范似乎是必不可少的;这些是libmat.solibmx.so

这些库又依赖于其他库,因此需要另一个标志来设置rpath.

最后它使用以下命令:

gfortran main.f90 dmotifs.o param.o ssa.o -I/usr/local/matlab2008a/extern/include -L/usr/local/matlab2008a/bin/glnxa64 -cpp -o main -lmat -lmx -Wl,-rpath /usr/local/matlab2008a/bin/glnxa64/

或一般来说

gfortran program.f90 -I<matlabroot>/extern/include -L<matlabroot>/bin/<arch> -cpp -lmat -lmx -Wl, -rpath <matlabroot>/bin/<arch> -o program.out

另请参阅中关于相同问题的这篇文章C

于 2015-05-12T09:40:14.860 回答