【问题标题】:MATLAB mex c + Fortran ErrorMATLAB mex c + Fortran 错误
【发布时间】:2013-09-13 17:11:05
【问题描述】:

我正在尝试混合一个由用 c 和 fortran 编写的文件组成的项目。 为了方便起见,我创建了这个简单的函数:

mysum.f

  SUBROUTINE mysum(a,b)
  REAL :: a,b,r

  r = a+b
  WRITE(*,*) r
  END SUBROUTINE mysum

和 test.c

#include <mex.h>
#include <stdio.h>

extern void mysum(double *a, double *b);
double a,b;

void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){

a   =(double) mxGetScalar(prhs[0]);
b   =(double) mxGetScalar(prhs[1]);

mysum(&a,&b);

return;
}

使用英特尔 Fortran 编译器 (x64) 我运行:

ifort /c mysum.f

它会创建 mysum.obj

在 Matlab (x64) 中,我使用 Microsoft SDK 作为编译器并编写:

mex -O -largeArrayDims LINKFLAGS="$LINKFLAGS /NODEFAULTLIB:MSVCRT.lib" test.c mysum.obj

不幸的是它给出了这个错误:

test.obj:错误 LNK2019:函数 mexFunction 中引用的未解析的外部符号 mysum test.mexw64 : 致命错误 LNK1120: 1 unresolved externals

此时我被卡住了,我不知道该怎么办。 我使用选项 /NODEFAULTLIB 是因为与 MSVCRT.lib 存在冲突。

我需要一些帮助。

【问题讨论】:

    标签: fortran mex fortran-iso-c-binding


    【解决方案1】:

    或者在 Fortran 中,您可以使用 ISO C 绑定并指定其他语言和链接器可以看到 Fortran 过程的名称,指定大小写而不需要下划线。您还可以声明变量,以保证与 C 的兼容性。在您的示例中,Fortran 默认 real 和 C double 可能不匹配。请参阅https://stackoverflow.com/questions/tagged/fortran-iso-c-binding 或 gfortran 手册(它是语言标准的一部分,因此那里的文档更普遍适用)。对于这个例子:

    SUBROUTINE mysum(a,b) bind ( C, name = "mysum" )
    use iso_c_binding
    implicit none
    REAL (c_double) :: a,b,r
    
    r = a+b
    WRITE(*,*) r
    END SUBROUTINE mysum
    

    【讨论】:

    • 请注意,iso_c_binding 模块仅适用于 Fortran 2003 及更高版本。 mysum.f 是 Fortran 90/95 之前的版本......它可能取决于编译器是否接受代码。使用模块时最好使用mysum.F90
    • 固定格式源在 Fortran 2008 中有效,编译器没有理由出现问题。此外,大写的 F 意味着应该使用 C 预处理器。
    【解决方案2】:

    您可能需要在 C 代码中的 mysum 后面附加一个下划线:

    extern void mysum_(double *a, double *b);
    
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]){
    //...
      mysum_(&a,&b);
    //...
    }
    

    运行nm mysum.obj 以获取所有子例程的正确名称。

    【讨论】:

    • 我使用的是 Windows,无法运行该命令。编译器帮助说它应该没有下划线。我尝试使用下划线,但没有成功。绑定解决了这个问题。谢谢
    猜你喜欢
    • 1970-01-01
    • 2015-01-10
    • 1970-01-01
    • 2016-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-05
    • 1970-01-01
    相关资源
    最近更新 更多