在 Windows 上使用 GFortran 在 Matlab 中创建 Mex 文件

Posted

技术标签:

【中文标题】在 Windows 上使用 GFortran 在 Matlab 中创建 Mex 文件【英文标题】:Creating Mex Files in Matlab with GFortran on Windows 【发布时间】:2017-03-17 21:17:22 【问题描述】:

我正在努力将 Fortran 例程添加到 Matlab 中(通过 Mex 函数)。我只是想编写一个简单的程序来了解 Matlab、Mex 和 Fortran 之间的链接是如何建立的。

我编写了一个简单的程序,它接收xy 的值,将它们相加并输出z。但是,当我在编译后尝试在 Matlab 中运行时,Matlab 只是在没有解释的情况下崩溃了。知道我在这里做错了什么吗?

! MEX FILE EXAMPLE
!


module yprime_mod ! test module for gnumex and g95
  use mexinterface
contains
  subroutine yprime(x, y, z) ! subroutine yprime(z, t, y, error, x)
    implicit none
    double precision :: x, y, z
    intent(in)  :: x, y
    intent(out) :: z
    ! 
    z=x+y;
  end subroutine yprime
end module yprime_mod

subroutine mexfunction(nlhs, plhs, nrhs, prhs)
  use yprime_mod
  implicit none
  integer :: nlhs, nrhs, plhs(nlhs), prhs(nrhs)
  double precision, pointer :: xp, yp, z
  !
  if (nrhs /= 2) call mexerrmsgtxt('yprime requires two input arguments')
  if (nlhs > 1) call mexerrmsgtxt('yprime requires one output argument')
  call c_f_pointer(mxgetpr(prhs(1)), xp)  ! assign pointers to parameters
  call c_f_pointer(mxgetpr(prhs(2)), yp)
  call c_f_pointer(mxgetpr(plhs(1)), z)
  call yprime(xp, yp, z)
end subroutine mexfunction

【问题讨论】:

对于 p*hs 参数,默认的 Integer 类型是否足够大?尝试将它们声明为mwPointers。此外,如果您直接使用 MEX Fortran API 编译它(没有干预 C),我认为您不需要 c_f_pointer 你能看看basic example for Fortran source files是否有效吗? 嗨@Adam 请问你是如何强迫matlab使用gfortran的?我读到只支持(非常昂贵的)英特尔编译器,我还想强制 Matlab 改为依赖 gfortran。谢谢! 【参考方案1】:

在不了解 Fortran 的情况下,我遵循了基本示例,并且它正在工作。

我对使用c_f_pointer一无所知(可能与崩溃有关)。 我认为代码很可能会崩溃,因为您忘记调用plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0) 来为返回参数创建矩阵。

这里是修改后的代码:

! MEX FILE EXAMPLE
!

#include "fintrf.h"

module yprime_mod ! test module for gnumex and g95
  !use mexinterface
contains
  subroutine yprime(x, y, z) ! subroutine yprime(z, t, y, error, x)
    implicit none
    double precision :: x, y, z
    intent(in)  :: x, y
    intent(out) :: z
    ! 
    z=x+y;
  end subroutine yprime
end module yprime_mod
!   
!    
subroutine mexfunction(nlhs, plhs, nrhs, prhs)
  use yprime_mod
  implicit none
  !integer :: nlhs, nrhs, plhs(nlhs), prhs(nrhs)
  !double precision, pointer :: xp, yp, zp
  !double precision x, y, z 

  !mexFunction arguments:
  mwPointer plhs(*), prhs(*)
  integer nlhs, nrhs

  !Function declarations:
  mwPointer mxGetPr
  mwPointer mxCreateDoubleMatrix
  mwPointer mxGetM, mxGetN

  !Pointers to input/output mxArrays:
  mwPointer xp, yp, zp

  !Arguments for computational routine:
  real*8 x, y, z

  if (nrhs /= 2) call mexerrmsgtxt('yprime requires two input arguments')
  if (nlhs > 1) call mexerrmsgtxt('yprime requires one output argument')

  !To points to the input matrices data, use the mxGetPr function.
  xp = mxGetPr(prhs(1))
  yp = mxGetPr(prhs(2))

  !Create Fortran arrays from the input arguments.
  call mxCopyPtrToReal8(xp,x,1)
  call mxCopyPtrToReal8(yp,y,1)

  !Create scalar for the return argument.
  plhs(1) = mxCreateDoubleMatrix(1,1,0)

  !Use the mxGetPr function to assign the y_ptr argument to plhs(1).
  zp = mxGetPr(plhs(1))

  !call c_f_pointer(mxgetpr(prhs(1)), xp)  ! assign pointers to parameters
  !call c_f_pointer(mxgetpr(prhs(2)), yp)
  !call c_f_pointer(mxgetpr(plhs(1)), z)

  !call yprime(xp, yp, zp)

  !Perform Calculation
  call yprime(x, y, z)

  !Copy Results to Output Argument
  call mxCopyReal8ToPtr(z,zp,1)

end subroutine mexfunction

我使用 Intel Compiler 进行编译,并在 Visual Studio 中逐步调试代码。mex 文件工作正常……

【讨论】:

嗨,亚当,您能就我的回答提供一些反馈吗?

以上是关于在 Windows 上使用 GFortran 在 Matlab 中创建 Mex 文件的主要内容,如果未能解决你的问题,请参考以下文章

不能在Ubuntu上使用gfortran和Abaqus 2016

在ubuntu上安装了gfortran编译器,出现了大问题哦!!求助啊!!

在 centos 6 中安装编译器 gfortran

gfortran 的问题:文件结尾记录似乎用未格式化的流文件记录得很糟糕

在ubuntu下安装fortran

编译使用带有gfortran的英特尔MKL模块的代码