TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
9 C* c% {7 S& x9 ?9 r5 b
说明
: @% O; n: o( C3 H1 O7 UMatlab混合编程
. `0 X) F( P6 Q& |; u A6 y下载与安装编译器5 ^# D. t& j. T9 ?
Microsoft Windows SDK 71CC
% U7 a6 H4 B7 Q# k" W& X- P$ R0 c9 RTDM-GCCgccg* r' h1 `; S. J
For Matlab 2015
# r4 z0 W/ ]2 F: \. j- }1 z4 \For Matlab 2014: x7 F, g* f$ H$ [( p3 @
选择编译器
9 P, C; b% t9 g2 K编写ccpp文件" }$ u1 S& \$ w7 c
mexFunction函数介绍
3 W2 g# i8 Y4 l& }9 q5 i* t8 }8 @8 j2 X编译多个ccpp文件1 Q1 ?3 J, q) |3 k1 D1 f/ i( ]* t9 _) o$ H
一些实例1 P+ F% H& D# ~1 g9 E# X
MATLAB2015编译MeanShift
% q( D) K6 N: M0 A0 H0 yProblemSolution
6 o9 T9 {0 {1 [找不到编译器或SDK
) h7 @) h9 r# D! q$ Y2 f+ aProblem
6 l+ J2 ~" l+ R4 W% ]Solution H5 R! a/ O" i
注意
! p$ B) L8 A# ^: eerror C2143 syntax error
4 o! F* p8 Q" F! y9 R+ i0 d& y B- OProblem
& \9 u8 T& a* ^! l! ?+ ?Solution
7 r* g& `0 ~7 [6 Q0 L一些有用的总结% r b) Y7 S& l
注意系统平台和文件路径* P* V5 P" ^" q- z
运行效率对比
0 S/ P/ ]- L( [5 T% d说明
+ q- J; g( H! C9 W& Y1 ~记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。# }+ A+ B$ T. ~) d8 G
; F* I7 v6 {8 ^: r$ m3 I/ |
- Matlab版本:Matlab R2014a 64-bit、Matlab R2015b 64-bit
- 操作系统版本:Windows 8.1 64-bit、Windows10 64-bit
- 编译器:Microsoft Windows SDK 7.1(C/C++) 和 GNU编译器(有MinGW(Minimalist GNU for Windows,仅32位)、MinGW64(64位和32位)、TMD-GCC(非官方的编译器包)、CygWin等等,它们间的区别与联系参见GCC_Cygwin_MinGW_TDM-GCC)! L$ t% M! ?# O$ O% X
: Y7 Q4 N* F1 e
4 X, G; r1 U3 j$ T Z/ q3 ]Matlab混合编程
& G$ t* E3 K+ k; Q( q下载与安装编译器
, v) P( W4 M8 [Microsoft Windows SDK 7.1(C/C++)
5 h% a+ M6 |8 A# l点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。7 g7 p% F6 l% ?" W3 I1 d, C
/ X! R1 q! U# L) `0 M
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。" D, ?: J* f; m4 Q( T$ b% R
1 i5 O" o5 N0 H g+ ]' j
TDM-GCC(gcc/g++). ^5 R8 S2 M% J R2 k
For Matlab 2015
& s* y3 k- i; P' J% e9 IMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
. t- u1 ?2 `8 z, ~
) i' s3 S& z. b& h, F5 p1 q- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:' K* `0 n3 S8 t2 {' g- ~
/ W$ S2 }' }$ g. F- 然后,还需注意的是安装路径不能有空格;
6 I/ E- G7 W% N z! f
/ i( L1 y. ~5 ?& j. W1 X- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:& Q9 S5 z& J! Q* e( D( F
3 _) p# r% Q+ r* z至此完成!% a" @1 e- L% g
" L. h1 L9 Y; W) W; C
/ O& X' K& w! s4 Q1 j$ XFor Matlab 2014
2 e/ x) P7 a# G0 B! t" Q+ H如下文章针对于MATLAB 2014a。4 ?$ G) S7 M. [1 S8 R8 A
& O9 ~) [" r) j- M. d* p S
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。% C; A+ z+ f) |" n6 j" |
* s1 @; A' U {8 M- t2 ? ^根据以前使用经验,安装路径最好不要有空格中文。4 ]# x4 s! Y A3 _' G
2 p( C, D/ U' H1 `5 B
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: ! A* |2 V- H% j
5 s7 x5 U c" H* C$ x7 I
, {/ o- h- Y9 K& ?最后的战斗:
. U6 l. ]' X1 Y$ b, P+ `! }/ [因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:$ e, K6 P9 B) s- ]3 u- {' ?
! P |+ O) c0 a% `- b$ @- j下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。" }2 \# u! E% c7 t
! }& Y! F9 J4 t$ i/ _
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
8 h( e- [& {" ^. X k, M! V6 L Y, Y$ e0 R6 J5 Q
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
7 \1 g# ^; Z1 [1 R5 t- B7 L% i
0 |: ~, z3 a1 }( \9 r下面是代码: G/ e6 _0 M9 m/ H8 T: v1 a. K
$ r0 N" U/ N2 m3 `' Y@Echo off
7 }/ v$ _/ X, c( c% L1 p4 K4 r. w% Y) o* h- O! }
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
+ K/ v. ^! z; P1 M6 P# U:: parses it and only understands a very reduced set of commands:
6 t9 u# w7 P5 t* W! P7 N; Y: [: X:: "set" and "rem" apparently, everything else is ignored (behaves as% y: L1 U3 Q- K! w! u& f/ W
:: "rem"), so don't do any fancy batch stuff in here. There are some
7 i" q8 W; Y0 p3 }( u5 d) {+ F:: undocumented special vars you can set here that will trigger MEX
8 M, Q( G4 I# X* w" Q% p& y" I:: to do fancy stuff.. @- N, a- i9 R7 D
! `0 `* K8 P3 R/ N
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
+ }' Q6 Y/ m* Z ^:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/( Y: a. L! H# f! Q& h- Y: v( u
- r& C2 u) f r( E:: Tested with the following:6 R: h+ Z8 h* i4 k. z8 \8 c; p! x
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/4.9.1/threads-win32/seh/x86_64-4.9.1-release-win32-seh-rt_v3-rev1.7z l/ W0 P8 W7 k, s& P8 c# p# @$ o
/ Y: k) q- c& G& v- z
:: Set this to your Mingw64 top folder, where you extracted the above; k6 T# \; n6 [/ H) r) P; e9 A
set MINGWPATH=p:\mingw648 J: k$ ~$ h; C( K; |- z
8 v. o6 l" D b' V
:: Leave these alone unless you know what you're doing.
9 H) E) |& e. b0 B- Q" U2 wset PATH=%MINGWPATH%\bin;%PATH%
1 U, t. n0 ^7 v3 x. Pset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs6 L5 c; Y; k# Y% C/ Q1 ?1 W; ~
+ K+ g) Q+ x. v, r+ |8 k0 }; b R:: You can have MEX run some commands before calling the linker.. T% f" |9 n$ Y$ w0 V. H# T% n
:: The two examples below will cause gcc to output the full path to some
0 N7 O3 y3 ^; y: Q3 F:: static libraries so you can link statically to them (see the; g3 q% d* G7 j: n* D
:: LINGFLAGSPOST special var below). You can set any command here, however.
- c% G% v: m& e0 o; K& P1 Erem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
" U; @" b; R! K; {) \rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs3 M; u% r1 K) n
rem set PRELINK_CMDS3=...
' ^; `5 G/ Z7 \$ Y! a. c) ]7 E4 s" ` ?3 a; E7 a, b6 Q4 U
:: You can have MEX run some commands also after calling the linker
% M3 y/ b" {6 v) z7 \:: (e.g. upx compress the output .mex)
* m% e9 C; l7 W6 |" l6 g" @1 m. e8 Rrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"5 m2 G5 H1 {% ~. b. V* b% `+ x
rem set POSTLINK_CMDS2=.../ H) S& H, s6 q# @1 Z& w3 X
' |7 }7 K- R+ c
:: You can change these if you really need to.' K, t$ g5 f: Y4 F& X5 @
set COMPILER=g++3 n) m* F2 t; y7 i5 Z t
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE' Z3 z$ c5 c8 o1 L
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG* F" z7 T) A" }" h
set DEBUGFLAGS=-g( y& y, v8 ?* q H& {# k6 j2 m
set NAME_OBJECT=-o
5 b7 @5 E4 }: w
4 G- c6 L! m* Gset LINKER=g++
" y3 w3 o7 t7 Wset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
s; u2 b" P* X
: a9 {: s f% z2 aset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
$ r8 [1 F3 X2 M7 m- z, bset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"3 m8 n' B! [, [5 O6 W0 S" u
4 N0 P; n/ {% Z0 q2 v! \- l" L( L6 }9 ]: q$ i+ t3 k
:: EXAMPLES
$ G# O' Z1 N: q' Q* Y% b:: ========0 q; H7 V7 D6 G" y! t q9 m: U
: T D8 Q3 u4 s6 Z% A:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
7 J5 i$ D; R) a! e:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
; Q$ x' ~9 e$ p3 [- B0 U5 L7 x7 m+ q
:: To add include dirs, lib dirs, or compile/link flags, do:
% a7 U0 g$ S: J/ s:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
/ Q, n2 V4 J& r" I
/ K# b* Q+ q+ Q# k
; {5 u0 I3 g. g% C: ?选择编译器
/ l4 V# D, v- t查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
: b' S! n% F$ P2 n* R5 b
4 i8 s2 j+ h1 x0 q( c, H
选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 2 N& E& |/ Z/ w C5 d
5 m( x' n5 O- `" M
如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: . Y5 m1 J8 n) ]& Y$ Q+ g1 B
2 h! c/ H) l/ F9 k; `
# a! p8 K' ~- R+ C
刚开始我也以为不能用,后来试着编译了一下,竟然可以!
) Y# J, v3 y3 a4 o9 V* m0 t0 [
8 ~' D( x5 l0 X' E/ F' `8 a
# U& C# b; m) K" Y% ?2 sDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
+ h& G# _/ ?% k) A' j2 X" D! N; c
8 l, }3 l' q" r
, P" E9 H/ {; o. A1 x$ F4 `; A编写c/cpp文件
9 M# R' G$ }1 e6 l1 d4 m% L5 i x, q7 p. F; ~ Z/ t
与普通的C文件的编写有两点不同:
+ I, P1 x K. M. G
' ]1 y, c) o) r( d) ^- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。
8 b# }) l, N1 B8 N+ S8 b4 w . Q: X+ R$ v* m' l" x3 f- y# y
下面以一个求和的例子说明:
: e) F7 {, L. ?4 U1 j+ E4 k' U/ F9 u* K+ m" ]- r1 f7 T3 h
#include "mex.h" // 使用MEX文件必须包含的头文件
$ ~+ `( W* b/ ]- D0 g, l) M" j: j8 p// 执行具体工作的C函数
5 K" U; z; b- e ^9 }- rdouble add(double x, double y)
p5 _% Z8 g$ z5 q0 A7 q# _{2 Z R' z( ~# k; c
return x + y;1 }! A) M( b9 A: T: i2 Q
}- v( P+ y. |; i
// MEX文件接口函数2 c# {7 X- n* \
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])/ _6 p7 C; m% y. T
{
3 |/ X0 p/ v4 E8 L8 i double *z;
3 C! T1 i7 S: e& x1 Z double x, y;
8 ^& ~, s* D( E plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
3 i. [! K9 ~) ?. G F' J z = mxGetPr(plhs[0]);
% R4 n1 I( A/ }6 [, ^ x = *(mxGetPr(prhs[0]));) ], O2 `; h; P& ]) y( S6 j4 j
y = *(mxGetPr(prhs[1]));, s% h9 _% p5 J3 t, D
*z = add(x, y);
& E4 \# w$ c, ^5 ~5 I+ r9 f}
' I& a* G. N9 o8 W: o# [
, @% |9 c. P/ J9 E
' W0 }! X5 E# h6 U. _Matlab命令窗口输入mex add.cpp,运行结果如下图: 2 I/ M& E& Z3 j9 Z u
) T) L. |' l& q c6 n4 _2 ]" `; A
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。% I8 u0 M9 y" Q2 S4 V/ X: K8 J4 X
. H2 k$ v* H3 q5 y$ O s6 S
mexFunction函数介绍
q7 p( d5 r( q9 M+ gmexFunction函数接口如下:, v. N7 \0 q( y
, P# [2 ]3 q: F+ }: }7 L. W W. W0 Dvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])* |/ C5 o8 q$ N. j P) ~' k
- {0 e$ a3 H/ H; S! L可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
1 h) I9 Y/ F6 ~5 ]# R/ N! ?& @2 w7 y6 _ S
参数 意义 英文全称 类型5 B: S0 [* i$ s
nlhs 左边输出参数的数目 number of left-hand side 整型(int)+ G" `3 O- f- l8 ?' F
plhs 指向输出参数的指针 pointer of left-hand side 指针数组; g6 `2 m: H% R- z1 J
nrhs 右边输入参数的数目 number of right-hand side 整型(int)
' l* j8 w0 `# }9 Q9 L8 xprhs 指向输入参数的指针 pointer of right-hand side 指针数组
: h& t: q# d3 ?& A1 G* }8 P- W详情参考:
8 U+ f' y2 t4 N9 p5 i" p/ M0 k: C2 n& E9 e. o4 L% x* O& h5 c' l& E
Matlab参考-MEX库) y4 L: T1 ]0 v: e8 ]/ Z
6 x( y! h) P9 K7 E7 ?4 J
MATLAB中mexFunction函数的接口规范(转载). c7 C L0 L. k7 K: D& X4 b
) X; `: i2 m5 G! n1 c5 j( YMatlab与C语言程序的应用编程接口
* F7 r! Y2 u0 Y+ w( H( ~* h' p" l1 |- s2 D: ]
matlab和C/C++混合编程–Mex
% c/ M# p7 y! N6 l& v* K% \
1 c0 r# B6 p0 q- y$ `编译多个c/cpp文件2 e& z O# _0 f
假设A.c调用B.c,B.c调用C.c
9 S1 S/ W! |4 M- {4 @可以使用如下命令编译:
9 A; G& e5 J. S& k7 _
7 _3 v7 _% c9 g% o% Q& Umex C.c
3 @" O9 u* }6 n/ f- r; I* m) amex B.c9 t, F3 D; K: l
mex A.c
: O3 @) H; t' B$ w, C \
' O; v1 M6 m) D! w$ O1 D. G4 W
{8 w8 W( M# I6 x或者0 x$ I: V) I7 h# ?
) ~* T& b2 S) K. Umex A.c B.c C.c/ X- L0 D& c! M, |
|
|