MATLAB: I don’t know Why the mex function associated with a Fortran 77 does not work. Can anybody help me

fortran codematlab coderMATLAB Compilermex functions

Mi code is:
#include "fintrf.h"
C======================================================================
#if 0
C
C PruebaMex.F
C .F file needs to be preprocessed to generate .for equivalent
C
#endif
C
C PruebaMex.f
C
C Computational function
C
C======================================================================
C Gateway routine
subroutine mexFunction(nlhs, plhs, nrhs, prhs)
C Declarations
implicit none
C mexFunction arguments:
mwPointer plhs(*), prhs(*)
integer nlhs, nrhs
C Function declarations:
mwPointer mxGetPr
mwPointer mxCreateDoubleMatrix
integer mxIsNumeric
mwPointer mxGetM, mxGetN
C Pointers to input/output mxArrays:
mwPointer FS_ptr, DF_ptr, y1_ptr
C Array information:
mwPointer mrows, ncols
mwSize size
C Arguments for computational routine:
real*8 FS_in, DF_in, y1_out(5)
INTEGER N
C-----------------------------------------------------------------------
C Get the size of the input array.
mrows = mxGetM(prhs(1))
ncols = mxGetN(prhs(1))
size = mrows*ncols
N = 1
C Create Fortran array and Scalar from the input argument.
FS_ptr = mxGetPr(prhs(1))
DF_ptr = mxGetPr(prhs(2))
call mxCopyPtrToReal8(FS_ptr,FS_in,size)
call mxCopyPtrToReal8(DF_ptr,DF_in,N)
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
y1_ptr = mxGetPr(plhs(1))
C Call the computational subroutine.
call PruebaMex(y1_out,FS_in,DF_in)
C Load the data into y_ptr, which is the output to MATLAB.
call mxCopyReal8ToPtr(y1_out,y1_ptr,size)
C call mxFree(FS_ptr)
C call mxFree(DF_ptr)
C call mxFree(y1_ptr)
RETURN
END
C-----------------------------------------------------------------------
C Computational routine
subroutine PruebaMex(y1_out,FS_in,DF_in)
IMPLICIT none
real*8 y1_out(*), FS_in(*), DF_in
INTEGER I
DO 503 I=1,5
y1_out(I) = FS_in(1)
503 CONTINUE
RETURN
END
I would appreciate it if someone could help me.
Thanks!!

Best Answer

1) "size" is the name of an intrinsic Fortran function that you shouldn't shadow. Pick a different name for your variable.
2) FS_in is defined as a scalar but you are potentially copying multiple elements into it. E.g.,
real*8 FS_in, DF_in, y1_out(5)
:
mrows = mxGetM(prhs(1))
ncols = mxGetN(prhs(1))
size = mrows*ncols
:
FS_ptr = mxGetPr(prhs(1))
:
call mxCopyPtrToReal8(FS_ptr,FS_in,size)
If size is bigger than 1, you will be writing into invalid memory and probably cause a crash. Not sure what your intent is here. Is the FS source at the MATLAB level supposed to be a scalar or a vector? I can't quite tell from your code. If a scalar, then you can use N (which is = 1) instead of size.
3) You could avoid all of the mxCopyEtc stuff by simply passing pointers around. E.g., this code
C Create Fortran array and Scalar from the input argument.
FS_ptr = mxGetPr(prhs(1))
DF_ptr = mxGetPr(prhs(2))
call mxCopyPtrToReal8(FS_ptr,FS_in,size)
call mxCopyPtrToReal8(DF_ptr,DF_in,N)
C Create matrix for the return argument.
plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
y1_ptr = mxGetPr(plhs(1))
C Call the computational subroutine.
call PruebaMex(y1_out,FS_in,DF_in)
C Load the data into y_ptr, which is the output to MATLAB.
call mxCopyReal8ToPtr(y1_out,y1_ptr,size)
could be simplified to this:
C\
C Create Fortran array and Scalar from the input argument.
C/
FS_ptr = mxGetPr(prhs(1))
DF_ptr = mxGetPr(prhs(2))
C\
C Create matrix for the return argument.
C/
plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)
y1_ptr = mxGetPr(plhs(1))
C\
C Call the computational subroutine.
C/
call PruebaMex(%VAL(y1_ptr),%VAL(FS_ptr),%VAL(DF_ptr))
Also note how I do commenting in Fortran which makes it easier for your brain to see the code vs the comments. Lining up your comments with your code simply makes extra work for your brain to separate these.