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.
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