Matlab 中使用 C/C++ 或 Fortran 代码的一种方式是利用 mex 进行编译,然后调用。
1 编译器设置
- mex -setup
有可能见到的信息是这个样子:
- >> mex -setup
- Welcome to mex -setup. This utility will help you set up
- a default compiler. For a list of supported compilers, see
- http://www.mathworks.com/support/compilers/R2012b/win64.html
- Please choose your compiler for building MEX-files:
- Would you like mex to locate installed compilers [y]/n? y
- No supported SDK or compiler was found on this computer.
- For a list of supported compilers, see
- http://www.mathworks.com/support/compilers/R2012b/win64.html
- Error using mex (line 206)
- Unable to complete successfully.
Matlab 无法完成自动搜索编译器,可以选择 n 再尝试。
- Welcome to mex -setup. This utility will help you set up
- a default compiler. For a list of supported compilers, see
- http://www.mathworks.com/support/compilers/R2012b/win64.html
- Please choose your compiler for building MEX-files:
- Would you like mex to locate installed compilers [y]/n? n
- Select a compiler:
- [1] Intel C++ 12.0 (with Microsoft Software Development Kit (SDK) linker)
- [2] Intel C++ 12.0 (with Microsoft Visual C++ 2008 SP1 linker)
- [3] Intel C++ 12.0 (with Microsoft Visual C++ 2010 linker)
- [4] Intel C++ 11.1 (with Microsoft Visual C++ 2008 SP1 linker)
- [5] Intel Visual Fortran 12 (with Microsoft Software Development Kit (SDK) linker)
- [6] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2008 SP1 linker)
- [7] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2008 Shell linker)
- [8] Intel Visual Fortran 12.0 (with Microsoft Visual C++ 2010 linker)
- [9] Intel Visual Fortran 11.1 (with Microsoft Visual C++ 2008 SP1 linker)
- [10] Intel Visual Fortran 11.1 (with Microsoft Visual C++ 2008 Shell linker)
- [11] Microsoft Software Development Kit (SDK) 7.1
- [12] Microsoft Visual C++ 2005 SP1
- [13] Microsoft Visual C++ 2008 SP1
- [14] Microsoft Visual C++ 2010
- [0] None
比较糟糕,无法匹配,用的是 2013 版的 Intel Fortran。可能需要自己编译了。
2 编译文件
- mex xxx.c
- mex xxx.f90
- mex -v COMPFLAGS='/fpp /Qprec "/ID:\PROGS\MATLAB\R2010A/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /fp:source /assume:bscc /libs:static /thread' LDFLAGS='$LDFLAGS -mt' supcrt.f supcrt92.f
- >> mex -v supcrt.f supcrt92.f
- This is mex, Copyright 1984-2007 The MathWorks, Inc.
- -> Default options filename found in C:\Documents and Settings\hu\Application Data\MathWorks\MATLAB\R2010a
- ----------------------------------------------------------------
- -> Options file = C:\Documents and Settings\hu\Application Data\MathWorks\MATLAB\R2010a\mexopts.bat
- MATLAB = D:\PROGS\MATLAB\R2010A
- -> COMPILER = ifort
- -> Compiler flags:
- COMPFLAGS = /fpp /Qprec "/ID:\PROGS\MATLAB\R2010A/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /MD /fp:source /assume:bscc
- OPTIMFLAGS = /O2 /DNDEBUG
- DEBUGFLAGS = /Z7
- arguments =
- Name switch = /Fo
- -> Pre-linking commands =
- -> LINKER = link
- -> Link directives:
- LINKFLAGS = /dll /export:MEXFUNCTION /LIBPATH:"D:\PROGS\MATLAB\R2010A\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib /implib:"F:\TEMP\MEX_VQ~1\templib.x" /MAP:"supcrt.mexw32.map" /NOLOGO /INCREMENTAL:NO
- LINKDEBUGFLAGS = /debug /PDB:"supcrt.mexw32.pdb"
- LINKFLAGSPOST =
- Name directive = /out:"supcrt.mexw32"
- File link directive =
- Lib. link directive =
- Rsp file indicator = @
- -> Resource Compiler = rc /fo "mexversion.res"
- -> Resource Linker =
- ----------------------------------------------------------------
- --> ifort /fpp /Qprec "/ID:\PROGS\MATLAB\R2010A/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /MD /fp:source /assume:bscc /FoF:\TEMP\MEX_VQ~1\supcrt.obj /O2 /DNDEBUG -DMX_COMPAT_32 supcrt.f
- ifort: warning #10268: Microsoft compiler version 6.0 or earlier is not supported
- --> ifort /fpp /Qprec "/ID:\PROGS\MATLAB\R2010A/extern/include" -c -nologo -DMATLAB_MEX_FILE /fixed /MD /fp:source /assume:bscc /FoF:\TEMP\MEX_VQ~1\supcrt92.obj /O2 /DNDEBUG -DMX_COMPAT_32 supcrt92.f
- ifort: warning #10268: Microsoft compiler version 6.0 or earlier is not supported
- supcrt92.f(664): warning #6375: Because of COMMON, the alignment of object is inconsistent with its type [ZPRTR]
- COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr
- --------------------------------------------^
- supcrt92.f(664): warning #6375: Because of COMMON, the alignment of object is inconsistent with its type [YPRTR]
- COMMON /refval/ mwH2O, R, Pref, Tref, ZPrTr, YPrTr
- ---------------------------------------------------^
- Contents of F:\TEMP\MEX_VQ~1\mex_tmp.rsp:
- F:\TEMP\MEX_VQ~1\supcrt.obj F:\TEMP\MEX_VQ~1\supcrt92.obj
- --> link /out:"supcrt.mexw32" /dll /export:MEXFUNCTION /LIBPATH:"D:\PROGS\MATLAB\R2010A\extern\lib\win32\microsoft" libmx.lib libmex.lib libmat.lib /implib:"F:\TEMP\MEX_VQ~1\templib.x" /MAP:"supcrt.mexw32.map" /NOLOGO /INCREMENTAL:NO @F:\TEMP\MEX_VQ~1\MEX_TMP.RSP
- Creating library F:\TEMP\MEX_VQ~1\templib.x and object F:\TEMP\MEX_VQ~1\templib.exp
- --> del "F:\TEMP\MEX_VQ~1\templib.x" "F:\TEMP\MEX_VQ~1\templib.exp"
- --> mt -outputresource:"supcrt.mexw32";2 -manifest "supcrt.mexw32.manifest"
- Microsoft (R) Manifest Tool version 5.2.3790.2075
- Copyright (c) Microsoft Corporation 2005.
- All rights reserved.
- --> del "supcrt.mexw32.manifest"
- --> del "supcrt.mexw32.map"
3 调用
很简单,直接调用即可。
- xxx
问题总结:
主要问题在于编译器的设置,需要安装特定版本的C/C++编译器和Fortran编译器,考虑自己编写脚本或CMake来编译。
实际上,mex文件就是一个导出了 mexFunction 函数的动态链接库文件,按DLL方式编译,加上导出信息即可。
- /export:MEXFUNCTION