MATLAB, gfortran, Windows - MEX (DLL) Interfaces

I am working on getting gfortran working with MATLAB on Windows. As far as I understand, the main issue is related to the name mangling; however, my understanding is naive, and there may be more to it than this. I would love it if you could explain it to me. I want gfortran and MATLAB to work on windows to keep using Fortran mex functionality of libraries that I have come across over the years. For instance, Glmnet is an example of a great library that once provided a mex binary that worked. As of the last couple releases of MATLAB, the Glmnet binary no longer works and therefore needs to be recompiled on Windows; For Linux, the recompile is trivially simple. I have contacted the author and received no response. Several years ago, I actually got gfortran to compile and link to MATLAB dll’s, but the mex function didn’t work. Now I am back again, trying to learn enough to see if what I have described is even possible.

The main method I use to get gfortran to compile and link against MATLAB is

  1. Generate a Module-Definition (.def) File using gendef for libmex.dll and libmx.dll (main dll’s needed for basic mex files). Modify the .def file mapping what gfortran is looking for in function name to what libmex.dll and libmx.dll provide. For example:

libmex.def

...
mexatexit_=MEXATEXIT
mexatexit800_=MEXATEXIT800
mexcallmatlab_=MEXCALLMATLAB
mexcallmatlab800_=MEXCALLMATLAB800
mexcallmatlabwithtrap_=MEXCALLMATLABWITHTRAP
mexcallmatlabwithtrap800_=MEXCALLMATLABWITHTRAP800
mexerrmsgidandtxt_=MEXERRMSGIDANDTXT
mexerrmsgidandtxt800_=MEXERRMSGIDANDTXT800
mexerrmsgtxt_=MEXERRMSGTXT
mexerrmsgtxt800_=MEXERRMSGTXT800
mexevalstring_=MEXEVALSTRING
mexevalstring800_=MEXEVALSTRING800
mexevalstringwithtrap_=MEXEVALSTRINGWITHTRAP
mexevalstringwithtrap800_=MEXEVALSTRINGWITHTRAP800
mexfunctionname_=MEXFUNCTIONNAME
mexfunctionname800_=MEXFUNCTIONNAME800
mexgetvariable_=MEXGETVARIABLE
mexgetvariable800_=MEXGETVARIABLE800
mexgetvariableptr_=MEXGETVARIABLEPTR
mexgetvariableptr800_=MEXGETVARIABLEPTR800
mexisglobal_=MEXISGLOBAL
mexisglobal800_=MEXISGLOBAL800
mexislocked_=MEXISLOCKED
mexislocked800_=MEXISLOCKED800
mexlock_=MEXLOCK
mexlock800_=MEXLOCK800
mexmakearraypersistent_=MEXMAKEARRAYPERSISTENT
mexmakearraypersistent800_=MEXMAKEARRAYPERSISTENT800
mexmakememorypersistent_=MEXMAKEMEMORYPERSISTENT
mexmakememorypersistent800_=MEXMAKEMEMORYPERSISTENT800
mexprintf_=MEXPRINTF
mexprintf800_=MEXPRINTF800
mexputvariable_=MEXPUTVARIABLE
mexputvariable800_=MEXPUTVARIABLE800
mexsettrapflag_=MEXSETTRAPFLAG
mexunlock_=MEXUNLOCK
mexunlock800_=MEXUNLOCK800
mexwarnmsgidandtxt_=MEXWARNMSGIDANDTXT
mexwarnmsgidandtxt800_=MEXWARNMSGIDANDTXT800
mexwarnmsgtxt_=MEXWARNMSGTXT
mexwarnmsgtxt800_=MEXWARNMSGTXT800
and more...
  1. Use dlltool to generate an Import Library as follows. I have tried dllwrap but haven’t been able to get it to work yet.
dlltool --def libmex.def --dllname libmex.dll --output-lib libmex.a
dlltool --def libmx.def --dllname libmx.dll --output-lib libmx.a
  1. Compile Fortran mex function.
gfortran -c -m64 -DMATLAB_DEFAULT_RELEASE=R2017b -DUSE_MEX_CMD -I"C:\Program Files\MATLAB\R2020b/extern/include" -I"C:\Program Files\MATLAB\R2020b/extern/include" -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer -fdefault-integer-8 -O2 timestwo.F
gfortran -c -m64 -DMATLAB_DEFAULT_RELEASE=R2017b -DUSE_MEX_CMD -I"C:\Program Files\MATLAB\R2020b\extern\include" -fexceptions -fbackslash -fPIC -fno-omit-frame-pointer -fdefault-integer-8 -O2 fortran_mexapi_version.F
  1. Link the objects and Import Libraries:
gfortran -m64 -static -shared timestwo.o timestwo.def fortran_mexapi_version.o libmex.a libmx.a libgfortran-3.dll -o timestwo.mexw64

The previous 4 steps complete without error. However, the mex library doesn’t work. I am missing a few things. If you can provide some explanation, that would be helpful. If I can’t get this figured out in the next couple of months, I will probably post a job and get some help on this. I really would love to compile Open Source Software and provide it for free on GitHub; many will benefit.

The calling conventions are a little different between gfortran and libmex.dll and libmx.dll. What I am really asking is can gfortran/GCC generate binaries that are compatible with libmex.dll, libmx.dll, etc. I hope so.

1 Like

Welcome to the Fortran community :raised_hands:
This is likely not the answer you were hoping for, but perhaps could be an alternative. As far as I know, MATLAB used to recognize only the Intel Fortran compiler on Windows: Compilers - MATLAB & Simulink
The good news is that the Intel Fortran compiler is now available on Windows free of charge. I have not run into problems with compiling Mex libraries on Windows via Intel Fortran compiler.

3 Likes

That is a good idea. I was not aware I could get a hold of the Intel compiler for free. I will give this a try.

@shahmoradi using Intel oneAPI (Intel Fortran 2021.2.0) worked. glmnet is working again!!! Thank you so much!

I still will work with gfortran a little to see if I can get it to work. Now I can examine the Intel compiling and linking commands along with the binaries it creates to see if there is a way to set up gfortran similarly. This is a great step forward.

1 Like