Main Content

Create Fortran Source MEX File

This example shows how to write a MEX file to call a Fortran subroutine, timestwo, in MATLAB® using a MATLAB matrix. You can view the complete source file here. This example uses the MATLAB Editor to write the source code and the MATLAB mex command to create the MEX function.

Fortran subroutine timestwo

The following code defines the timestwo subroutine, which multiplies an n-dimensional array, x_input, by 2, and returns the results in array, y_output.

      subroutine timestwo(y_output, x_input)
      real*8 x_input, y_output

      y_output = 2.0 * x_input
      return
      end

Create Source File

Open MATLAB Editor, create a file, and document the MEX file with the following information.

C======================================================================
C     timestwo.f
C     Computational function that takes a scalar and doubles it.
C     This is a MEX file for MATLAB.
C======================================================================

Add the Fortran header file, fintrf.h, containing the MATLAB API function declarations.

#include "fintrf.h"

Save the file on your MATLAB path, for example, in c:\work, and name it timestwo.F. The name of your MEX file is timestwo.

Create Gateway Routine

MATLAB uses the gateway routine, mexfunction, as the entry point to a Fortran subroutine. Add the following mexFunction code.

C     Gateway routine
      subroutine mexFunction(nlhs, plhs, nrhs, prhs)

C     Declarations

C     Statements

      return
      end

Add the following statement to your mexfunction subroutine to force you to declare all variables.

implicit none

Explicit type declaration is necessary for 64-bit arrays.

Declare mexfunction Arguments

To declare mxArray variables, use the MATLAB type, mwPointer. Add this code after the Declarations statement.

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

Declare Functions and Local Variables

  • Declare the symbolic names and types of MATLAB API functions used in this MEX file.

    C     Function declarations:
          mwPointer mxGetDoubles
          mwPointer mxCreateDoubleMatrix
          integer mxIsNumeric
          mwPointer mxGetM, mxGetN

    To determine the type of a function, refer to the MATLAB API function reference documentation. For example, see the documentation for mxGetDoubles.

  • Declare local variables for the mexfunction arguments.

    C     Pointers to input/output mxArrays:
          mwPointer x_ptr, y_ptr
    
  • Declare matrix variables.

    C     Array information:
          mwPointer mrows, ncols
          mwSize size
    

Verify MEX File Input and Output Arguments

Verify the number of MEX file input and output arguments using the nrhs and nlhs arguments. Add these statements to the mexfunction code block.

C     Check for proper number of arguments. 
      if(nrhs .ne. 1) then
         call mexErrMsgIdAndTxt ('MATLAB:timestwo:nInput',
     +                           'One input required.')
      elseif(nlhs .gt. 1) then
         call mexErrMsgIdAndTxt ('MATLAB:timestwo:nOutput',
     +                           'Too many output arguments.')
      endif

Verify the input argument type using the prhs argument.

C     Check that the input is a number.
      if(mxIsNumeric(prhs(1)) .eq. 0) then
         call mexErrMsgIdAndTxt ('MATLAB:timestwo:NonNumeric',
     +                           'Input must be a number.')
      endif

Create Computational Routine

Add the timestwo code. This subroutine is your computational routine, the source code that performs the functionality you want to use in MATLAB.

C     Computational routine

      subroutine timestwo(y_output, x_input)
      real*8 x_input, y_output

      y_output = 2.0 * x_input
      return
      end

A computational routine is optional. Alternatively, you can place the code within the mexfunction function block.

Declare Variables for Computational Routine

Put the following variable declarations in mexFunction.

C     Arguments for computational routine:
      real*8  x_input, y_output

Read Input Array

To point to the input matrix data, use the mxGetDoubles function.

x_ptr = mxGetDoubles(prhs(1))

To create a Fortran array, x_input, use the mxCopyPtrToReal8 function.

C     Get the size of the input array.
      mrows = mxGetM(prhs(1))
      ncols = mxGetN(prhs(1))
      size = mrows*ncols

C     Create Fortran array from the input argument.
      call mxCopyPtrToReal8(x_ptr,x_input,size)

Prepare Output Data

To create the output argument, plhs(1), use the mxCreateDoubleMatrix function.

C     Create matrix for the return argument.
      plhs(1) = mxCreateDoubleMatrix(mrows,ncols,0)

Use the mxGetDoubles function to assign the y_ptr argument to plhs(1).

      y_ptr = mxGetDoubles(plhs(1))

Perform Calculation

Pass the arguments to timestwo.

C     Call the computational subroutine.
      call timestwo(y_output, x_input)

Copy Results to Output Argument

C     Load the data into y_ptr, which is the output to MATLAB.
      call mxCopyReal8ToPtr(y_output,y_ptr,size)     

View Complete Source File

Compare your source file with timestwo.F, located in the matlabroot/extern/examples/refbook folder. Open the file in the editor.

Build Binary MEX File

At the MATLAB command prompt, build the binary MEX file.

mex -R2018a timestwo.F

Test the MEX File

x = 99;
y = timestwo(x)
y =
   198

See Also

| | | | | | |

Related Topics