使用Fortran的MATLAB引擎API,我试图从Fortran代码中调用一个简单的MATLAB函数。
我遵循了这里的fengdemo示例。它起作用了,所以我想调整我的Fortran代码,以调用我编写的特定Matlab脚本。
我的MATLAB脚本call_fortran.m
非常简单:它将x
作为一个条目,并将其乘以2
:
function multiply = call_fortran(x)
multiply = 2*x;
end
我希望我的FORTRAN代码生成一个变量my_x
,打开一个MATLAB会话,将变量发送到工作空间,应用函数call_fortran
并显示结果。使用fengdemo.f代码,我写道:
program main
C Declarations
implicit none
mwPointer engOpen, engGetVariable, mxCreateDoubleMatrix
mwPointer mxGetPr
mwPointer ep, my_x ! ep: variable linked to engOpen, starting a Matlab session, my_x: variable que je veux donner a Matlab
double precision my_x
integer engPutVariable, engEvalString, engClose
integer temp, status
mwSize i
my_x = 6
ep = engOpen('matlab ')
if (ep .eq. 0) then
write(6,*) 'Can''t start MATLAB engine'
stop
endif
C Place the variable my_x into the MATLAB workspace
status = engPutVariable(ep, 'my_x', my_x)
C
if (status .ne. 0) then
write(6,*) 'engPutVariable failed'
stop
endif
! My issue now is to call the correct Matlab script
! nlhs = 1
! plhs = 1
! nrhs = 1
! prhs = 1
! integer*4 mexCallMATLAB(nlhs, plhs, nrhs, prhs, functionName)
所以我有我的my_x
,我把它发送到MATLAB,但我如何应用call_fortran.m
函数并获得my_x
的新值?
此代码有两个基本错误。您没有为my_x使用正确的变量类型,也不能从Engine应用程序(只能在mex例程中使用(调用mexCallMATLAB((。让我们来解决这些问题。首先,my_x变量需要是mxArray,而不是双精度变量。有多种方法可以做到这一点,但对于标量,创建此数组的最简单方法如下:
mwPointer, external :: mxCreateDoubleScalar
mwPointer my_x
my_x = mxCreateDoubleScalar(6.d0)
然后,您可以根据当前代码将其传递给MATLAB引擎。要在MATLAB引擎工作区中调用函数,需要在那里评估一个字符串:
integer*4, external :: engEvalString
integer*4 status
status = engEvalString( ep, 'result = call_fortran(my_x)' )
结果应该显示在引擎工作区中,因为我们没有用分号终止字符串。如果您想将结果返回到Fortran代码中,则需要执行以下操作:
mwPointer, external :: engGetVariable
mwPointer result
result = engGetVariable( ep, 'result' )
Fortran代码内部的结果将是一个mxArray。要提取数字,有多种方法,但对于标量,最简单的方法如下(使用实数*8而不是双精度来精确匹配文档中的MATLAB API签名(:
real*8, external :: mxGetScalar
real*8 myresult
myresult = mxGetScalar(result)
为了避免内存泄漏,一旦处理完mxArray变量,就应该销毁它们。例如,
call mxDestroyArray(my_x)
call mxDestroyArray(result)
写了所有这些,你确定要创建MATLAB引擎应用程序,而不是mex例程吗?Mex例程通常更容易使用,并且不涉及额外的数据副本来将变量传递回&向前地