TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
1 E0 _& L* o. X) ^# ]2 O1 O7 Z说明
4 K0 p1 n* c \$ B$ K& w# }Matlab混合编程
2 U+ H$ R" }8 ^& ^下载与安装编译器4 }$ ]; M; F r4 T$ U, ^9 L( V6 K
Microsoft Windows SDK 71CC
# U/ K2 U# B" \3 S& I: f! jTDM-GCCgccg
& s4 W( B% `1 l1 dFor Matlab 2015* N3 [" t: Z, m( p6 e
For Matlab 20146 t& a* O) d) |. S* V! h8 w/ [
选择编译器/ e! B0 C" n, ]4 q* \1 A1 ]
编写ccpp文件
5 b" b5 w0 [# u) \! h# x- BmexFunction函数介绍: { s! t7 q+ s: {8 D) B/ a: o
编译多个ccpp文件, m* x" v5 J- b# y
一些实例
}( {$ o) i, |7 E" }MATLAB2015编译MeanShift; k9 Z2 L+ L$ Q3 F* l1 Y
ProblemSolution
; X' S6 e" L( L; n. g找不到编译器或SDK6 N6 g$ _/ u1 `1 |$ s) s. Z
Problem
6 ]' M$ U7 ^( y. y6 K6 a2 KSolution' u* j. e: H& ]9 W" G
注意
4 C9 Q4 `+ i7 i3 `; @- Eerror C2143 syntax error/ [' s b2 A1 i! P9 V' U2 O
Problem" \9 S, [( G$ h+ }( _
Solution$ _' b; F+ i I1 W& r
一些有用的总结
7 |. {4 N8 X: F4 X1 R+ r9 Y: m注意系统平台和文件路径
6 R" N: h! r3 \( }运行效率对比
! d9 y$ r! q, y! x( D3 G说明
; j' ~1 j- C' _. t记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。1 U4 T. S/ T9 a
$ e: h* `: w! S3 C% O0 F- 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)5 f% @1 ?' Q- c a; b1 `7 N
& r. ^4 j+ L) i/ ^
( @0 ?. B. y* N+ t! B A
Matlab混合编程
- R; [9 }0 b4 C; T下载与安装编译器8 `% p( O- H1 y7 m. g" u
Microsoft Windows SDK 7.1(C/C++)+ f1 m* n, ~1 H
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。' \9 Q# f6 v& A6 c
6 d Y! Q- ~2 [, h: N4 ]. t
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。. M/ N7 V5 N1 k% ?4 Y' Q% Y" |* Q
0 V# U6 d l6 R0 V/ STDM-GCC(gcc/g++)
+ Z' y1 \; M8 a$ T5 o7 XFor Matlab 2015! |9 Y+ t0 |5 P p
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。) f+ c" B) y/ d# [, b$ v5 Q
}8 H7 n* _, Z0 H. _; r0 P
- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:+ Y1 m; J1 S7 Q7 D, e
7 `- D4 S- W! s
- 然后,还需注意的是安装路径不能有空格;
2 `* ~$ ]; P* S. E2 C7 e8 ]
3 y' [- u( f2 H: c6 b0 c( c1 g* V- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:1 B# A' |2 c) K3 {3 }& D) q
9 [4 ^: d `) s8 A至此完成!0 _, U# ?( |6 t0 a, q/ n
9 H; W8 b+ u3 \, g; o P* ^5 ]; s- ?, r) s- A9 J
For Matlab 2014
3 M0 W: M1 C1 T) {4 j1 w6 S, C如下文章针对于MATLAB 2014a。. s+ y* I+ i, s7 |, U" u, h& c
w& T- j8 s4 o( T) {2 H( y6 R+ M点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。6 X, `5 Q0 S( @" _0 W6 g) q* F) W! z/ ~! I
2 ^0 t1 @- v' m根据以前使用经验,安装路径最好不要有空格中文。
& P% n6 y6 E) Q7 V6 i6 t% r! L, c% G2 H- T3 D3 c/ A2 @# j
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
+ f+ K& C7 ?! Z- E
2 @: J+ w1 Z) u8 @# m, d+ O$ H+ I' P
最后的战斗: ( B9 U/ E3 _ ?# e) O8 ?+ i
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:
0 S2 _8 L7 L# N H% c$ [- y3 o0 m+ N5 f
+ T7 Y& t0 J$ L5 m3 O- J* Q3 |下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
, x: B4 A* a; Q/ b2 `8 Y6 B+ W/ X1 m; Q( b* w& X9 N0 o& E1 `
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):9 F" z( k/ w# i6 l: P
- X7 ?/ W4 k# R' |; V2 T5 v
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\$ M5 L. p z* M8 A
# N0 t( @" u8 h4 H# G: }下面是代码:
4 k2 ^( |& `+ _$ C+ K# a5 x; F0 R; |5 H/ A& S$ W
@Echo off0 I1 ]6 V) w$ Y: D( Q
: U4 m0 a9 E9 a9 c
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX& X* x' A3 ^) B( E2 }: s" a
:: parses it and only understands a very reduced set of commands:* {8 [6 ]7 j: C' g- ]" X' d2 B, c) V2 P
:: "set" and "rem" apparently, everything else is ignored (behaves as( f0 `4 u" a2 f8 ]
:: "rem"), so don't do any fancy batch stuff in here. There are some% ]! @* f3 x; r! r
:: undocumented special vars you can set here that will trigger MEX
9 P% d+ [& x0 ?3 ?/ z( Q( g:: to do fancy stuff.
' g3 s( i# Z: Y$ }" T
# q5 k+ I* C+ I' c5 V:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
) c# ^& z8 I2 l:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/1 q f4 N6 m! J" ^: s! X$ }' i" l9 _
6 x. Z1 q# r9 h3 ^/ P( W- w
:: Tested with the following:8 N( t( j8 k, Z& J
:: 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 I" p( O+ }$ b
/ y8 Q( a' d& G( W' {:: Set this to your Mingw64 top folder, where you extracted the above" y( r% e$ ^+ U# R
set MINGWPATH=p:\mingw64
: q* U5 ~- E- a4 b
; L+ P: R( V5 T& }:: Leave these alone unless you know what you're doing.) I k8 g2 m! K3 o3 m" m+ q
set PATH=%MINGWPATH%\bin;%PATH%
* G2 B/ ^) M- }4 G; {set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
* I4 l- X& |* V8 k. l- z* \# f' ?6 a4 b1 D
:: You can have MEX run some commands before calling the linker.+ J, B* ~: X! J# `# L5 o
:: The two examples below will cause gcc to output the full path to some
$ h+ W9 r% ?2 U) I' c* Q" A:: static libraries so you can link statically to them (see the
/ G/ {2 r. A* o9 t:: LINGFLAGSPOST special var below). You can set any command here, however.6 e2 q. Y% H4 ~( z$ z
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs- T" M$ Z* J/ `* I4 I) x
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
- T, w1 m1 ]* Jrem set PRELINK_CMDS3=...! I7 e7 g l/ _4 Z+ H. F8 Z% x
1 K7 t0 d0 Z! l5 y+ E
:: You can have MEX run some commands also after calling the linker" _% G0 ^8 Q# _6 R! o
:: (e.g. upx compress the output .mex)
2 H, V, Y- J+ u$ {" G1 Wrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"6 O& j( e: ? c6 c
rem set POSTLINK_CMDS2=...( h$ g3 A3 }! i) J8 z- x- [
7 C# C% t2 ^8 ]& ], j:: You can change these if you really need to.- m' j, d7 k8 u
set COMPILER=g++
; c* q+ l0 ^$ [- [, mset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE7 o! a) r0 u% ]( R& M0 m. G
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
( u9 k9 U- {0 A# k5 r8 I* a9 Dset DEBUGFLAGS=-g
3 }+ w- u+ v1 Lset NAME_OBJECT=-o
6 K7 i9 t: a& d2 P+ o+ L, v# f
" @5 C1 C; }/ g1 w' cset LINKER=g++
/ Z6 u7 H- U* x. L+ G- _& uset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
6 a6 w! v, `, g. G
6 T& e, _" b% E& Q. e% G6 |set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
% H0 t0 q0 }9 S p% Fset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
, g0 R+ d, B+ d' F) q
, t& Q+ {7 R# P- Y& a! g9 H
; [2 K" T% r6 \* \2 l; y J:: EXAMPLES
3 t* F$ b" y7 ]3 {7 T+ V:: ========' L% i( @4 i" ]" ~
# w. S5 s- j2 H# u1 q) k2 _:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use5 a& S' O" `' y3 J
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
- E- j k5 r5 H" L5 Z% \" R4 t& x, N8 T4 W+ d, A* l, `8 {
:: To add include dirs, lib dirs, or compile/link flags, do:
5 a$ J9 G m; c. H8 }" G:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
) Q" A" o+ U, p+ G Z7 m
; l; o/ ~9 g0 c; m- f0 Q5 `/ B* u) d* x" H& F
选择编译器
c A0 T5 Q5 m4 H查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: 9 d) |$ |1 O2 {6 b b5 \7 C- e
" e- v p; Q- _+ p) q+ m
选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
% F4 h; A. q+ a! e* R$ C
; C: I7 o- T( M3 \7 ]7 B如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: , U( T9 {9 f/ J
0 ^2 g, ^0 R5 b" c
r4 I% ] _2 z/ {8 Z' m1 O刚开始我也以为不能用,后来试着编译了一下,竟然可以!
2 K( r+ W/ g+ q9 H' V$ f
7 y: g* U8 g5 o9 ]
7 n+ \& }. e4 B# ~DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!* o+ b9 n1 p; g1 [, p$ S4 q! U
9 Y" p5 K; o6 \0 H* \
/ v& y% F7 N0 s
编写c/cpp文件
( b; \# B: J- k
# K' ~) T) ]7 x- a- j E) _与普通的C文件的编写有两点不同:, {% U; \+ A$ W7 c. |
) y, e+ Y# g3 `3 S8 I! J- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。9 G: T3 y3 S- r+ R1 ]6 Y% ]- ~
3 _7 I; ]1 O: g+ k7 _4 a下面以一个求和的例子说明:
' a3 K4 [% D2 [! c
9 H! ~* O+ I1 A& e! \3 R s ?#include "mex.h" // 使用MEX文件必须包含的头文件
4 q/ U* w/ ^8 A; x9 v# `" `$ q// 执行具体工作的C函数
" d0 g: I/ j0 R$ Y4 B/ s# ?. v+ _4 Hdouble add(double x, double y)9 i% F) _* o+ k. j( i5 Q- \" T
{% c$ o4 b; A1 ~; V5 K( ~2 a7 e
return x + y;
, i8 p9 i4 |! B$ t}
: ?. U( ~% Y/ J/ q# Z/ {// MEX文件接口函数
4 F v6 s2 X( qvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])3 |; ^+ v, T& o% r. B3 t$ l# Y
{, E! g; Z( f) O) _
double *z;& L; e$ S% ]) }8 S# j8 l# x% [
double x, y;# V2 s5 `. g+ R( _
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);' R, @6 @/ {, }
z = mxGetPr(plhs[0]);9 }$ ?# Y5 r5 c/ f
x = *(mxGetPr(prhs[0]));
) ^6 r* c. |- n% a3 V y = *(mxGetPr(prhs[1]));
* T2 t# r. I+ B+ M) f0 m. ]$ @9 r *z = add(x, y);
; N8 \) s ?# L& g* W( h# @! S' h}
2 a1 `+ ~7 L& A8 I+ L- y9 U+ D
E! F6 \ E7 r. a O r
Matlab命令窗口输入mex add.cpp,运行结果如下图: * N" |$ x; i/ W: s
8 X- [3 J$ ]) r( W9 B8 t i* d5 ]5 h3 b* O! \! M3 @
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
# E/ [5 i/ @+ k4 I% l9 k+ M; E' J9 S N. E% ]2 l+ J" v
mexFunction函数介绍
i Y A5 E6 B( x4 ~$ @$ JmexFunction函数接口如下:/ s+ O" n3 f: r/ e7 {
2 `! }1 Z4 j5 {/ V6 \0 ^
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
, C- e' d% I+ @1 W8 h0 a# l' P5 t8 @0 c5 t* Y
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:# M( v" e: ?% C' _0 w+ }
/ k% l7 U# j2 ~$ |
参数 意义 英文全称 类型/ j4 V( W) }; m1 x* l" f
nlhs 左边输出参数的数目 number of left-hand side 整型(int)6 f6 ^5 ?7 v0 I! C4 M1 @
plhs 指向输出参数的指针 pointer of left-hand side 指针数组
2 { A, A2 p! O9 J" Inrhs 右边输入参数的数目 number of right-hand side 整型(int)
2 z& ^3 X* |. vprhs 指向输入参数的指针 pointer of right-hand side 指针数组 M% f; Z/ G3 `9 b$ [
详情参考:
7 [, |$ x3 o1 S" W
) ]4 c7 Z) ?' x) W2 kMatlab参考-MEX库
5 V( t8 y1 d" m
7 a: z( e6 I: ]1 c% QMATLAB中mexFunction函数的接口规范(转载)
' W* a: N2 F) n8 S% F* o. R/ R8 o, x. ]: d2 |0 D3 Y* ?
Matlab与C语言程序的应用编程接口$ N) ~1 g0 n( v* l
. z# x( T1 Y' a: j* Y6 b. fmatlab和C/C++混合编程–Mex
6 M& n' F P) J$ D1 F
: f* Z* O0 L8 F编译多个c/cpp文件
1 J0 j4 C, e t假设A.c调用B.c,B.c调用C.c ! K* q# r" p8 e' w7 w* }
可以使用如下命令编译:+ H9 {) Y+ R9 v; n" v
# p, b/ q0 K/ C7 [mex C.c8 \; w: H; \ d5 g1 @$ D
mex B.c( R8 [1 j$ F! T0 g' q
mex A.c
7 S0 a1 m5 l; x) M* i7 N1 K) g' U) Q s9 d% V$ [5 x
2 W/ C# L3 @# W% x或者
$ e c' Y. t$ _( J3 M* f8 y# h
# }0 ?6 s) N4 hmex A.c B.c C.c& t; f5 ]* a' m5 A# ]& c
|
|