-1

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

我的总和

  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 test.mexw64 中引用的未解析的外部符号 mysum:致命错误 LNK1120:1 个未解析的外部符号

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

我需要一些帮助。

4

2 回答 2

1

或者在 Fortran 中,您可以使用 ISO C 绑定并指定其他语言和链接器将看到 Fortran 过程的名称,指定大小写而不需要下划线。您还可以声明变量,以保证与 C 的兼容性。在您的示例中,Fortran 默认值real和 Cdouble可能不匹配。请参阅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
于 2013-09-14T04:59:19.683 回答
0

您可能需要在 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以获取所有子例程的正确名称。

于 2013-09-13T17:43:54.937 回答