TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
2 X) ~3 g4 \. y0 n4 J( ?9 `说明
. l1 L9 P" r, AMatlab混合编程
7 H: T& I5 W$ k1 |) n% z下载与安装编译器
2 F+ U5 |' z2 C- JMicrosoft Windows SDK 71CC/ b# G' V" @" g1 ?3 D% H, I
TDM-GCCgccg
9 G W+ X9 k# J% UFor Matlab 2015
6 x, y) d* D* b6 ~4 @& d jFor Matlab 2014( ~! c! v$ C& m$ G( X
选择编译器
+ x( T. `/ w; u0 F: U ~5 T5 ]: i编写ccpp文件% m% b/ ]+ F+ D0 y4 a
mexFunction函数介绍9 v. n2 ~! V; m& c
编译多个ccpp文件& Y9 q ~: i% V/ H$ W2 C
一些实例
, p1 I" o: X% x/ O6 o- C" PMATLAB2015编译MeanShift" E% t$ v' x n1 D( b
ProblemSolution
: _+ P. { {# L找不到编译器或SDK
1 z& A7 N0 R% LProblem
5 q: P* b6 E$ r$ E$ ASolution$ m0 C1 B+ C. @% i
注意
7 F) j! n, ]# R# ^) L/ A$ qerror C2143 syntax error' l% m+ g4 t) H: R9 `; L
Problem
; X, a6 e* q% C2 w1 i8 M8 f$ [/ TSolution
2 s1 i# P U8 ]/ W N. C一些有用的总结
6 u( y9 S- H4 I4 S/ i注意系统平台和文件路径 {9 ?* n* n9 {: L
运行效率对比
4 T, e0 M& p, D" W% r! O说明8 K c4 u7 h5 P1 B6 d
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
0 U' H+ j. ]% `
$ w) ]) s! T1 e6 p* w) p$ J- 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)
- n# D1 I2 C! ]5 z7 `' O9 N6 N $ T4 S, y1 h# x( n I& _; B
. Q, @' D' I9 P0 {& fMatlab混合编程
' O9 o+ l4 q- G o7 }下载与安装编译器
9 @, v/ r! m8 E. i, tMicrosoft Windows SDK 7.1(C/C++)4 p3 z. z1 \' N7 b( B2 ^
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
& X! P5 _: `& k1 r9 G. S) K$ \' q, z; l
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
3 W7 `$ F& V `9 P7 {" \4 X- ]
4 g9 P+ l' N: l4 ~TDM-GCC(gcc/g++)5 D, Z" f6 `8 t1 n" ~
For Matlab 2015
6 \/ R, G0 r7 m# DMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
( J8 z' M8 |2 ~: y
# L6 E2 w, h+ Y$ U* R% `- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
0 u( x* R7 _, X# u3 [+ s
0 `9 t+ p- ~7 Q" O* f
- 然后,还需注意的是安装路径不能有空格;3 V$ x0 k2 r! D, U7 B
+ e3 W8 c. t+ c8 e" X
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
, _9 G% x ^5 O" a) {" e
: }+ d; F% ~3 \+ C; A+ e7 q至此完成!
7 Z) f% N; i: u2 x1 E: E; W( S# O! H9 N% W+ [+ T. X# ^
" Z }+ D9 p' ]; y- Q& e j
For Matlab 2014; X. g u# f& U& V, z4 x. ]/ d/ L) T
如下文章针对于MATLAB 2014a。
' Y9 T6 z9 [# v4 i( c) D' y8 G& {: J% h% R' i# z
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。( W) Z/ X0 h- o. c0 ~
s; N6 \$ R. o' ^6 F
根据以前使用经验,安装路径最好不要有空格中文。
0 ^' d$ M! `$ n; d# }9 _; y; [. `5 g% e4 [, O) t
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
% _# F( q! k% `2 F" X
c; Q- w) N% J; \
: B0 w8 Q! L6 T. V4 \
最后的战斗: ! P& A7 }" B1 i! g$ K$ v
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:6 \! }7 u' i; A Q1 U7 j5 f/ O9 ?) _8 I
' ~3 l- J4 U5 `. u7 F% z
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。- ?0 T6 m) q$ n1 X* [1 }
1 h: [' h- h" h- Y2 O$ t在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):, o* b! `2 g1 e4 q" w
C5 x5 f7 L; f0 i$ L5 ~2 }
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
: o- o' Z2 Y1 u& V3 P+ d
* f- m! |; G( |- c! j% d7 g下面是代码:+ z. ]" _% o' S' K7 j& ]( \
: |% {+ T; X* [@Echo off, Q' _( o5 R8 I5 O, ^3 u" H
. K$ Y# G) |/ ~9 v+ o' v
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
6 f% V Q# q3 z: O: p! L:: parses it and only understands a very reduced set of commands:+ C5 Q3 @9 Q5 C5 @8 Z
:: "set" and "rem" apparently, everything else is ignored (behaves as
n% G; {3 s4 f& T, W* A0 M! Z: _& S# M:: "rem"), so don't do any fancy batch stuff in here. There are some
0 i" ~1 s9 K( ~ y( W:: undocumented special vars you can set here that will trigger MEX
- b$ h) D; f' a:: to do fancy stuff./ V$ W3 Z6 W( G2 k7 k1 R4 @
8 F! f: l O$ Z- o& X:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:/ z0 I+ ?/ p# I: l4 M
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
9 p5 J+ A3 w) H8 x
1 ~8 s; i2 t) s1 ?2 h:: Tested with the following:! Z% x7 _+ \' s6 g$ D1 I
:: 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/ ~/ N) l2 H4 f, f
6 z- q7 ?1 M2 a I+ K# L: p% Y
:: Set this to your Mingw64 top folder, where you extracted the above6 [; t2 A3 Y4 X# o( q" Q( w/ J
set MINGWPATH=p:\mingw64
* M: c% U8 @/ m2 k; u& r
* e8 k n6 [) E% P:: Leave these alone unless you know what you're doing.1 `9 k, z o1 ~$ H( H( _# C* @1 v* t
set PATH=%MINGWPATH%\bin;%PATH%
7 j6 G2 J+ o& k1 r7 iset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs X/ @) [: @" e) V: h
& X6 |* i) _+ \:: You can have MEX run some commands before calling the linker.
- V" k+ x6 @# F: H6 }/ b# j:: The two examples below will cause gcc to output the full path to some
2 a3 H$ s& e9 C# A+ }:: static libraries so you can link statically to them (see the
- Y' Q \7 l' A: a+ N; k" ~:: LINGFLAGSPOST special var below). You can set any command here, however.
9 E$ X5 H4 Z( Irem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs; r5 I4 B6 _2 J2 A; D: n
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs$ l, D! ]- b8 K0 ~4 V8 D, u
rem set PRELINK_CMDS3=...# A" }9 k6 a2 z8 k. A
/ n" p I8 ]9 c6 K1 k:: You can have MEX run some commands also after calling the linker: Y7 s P8 r/ n' X W* H) i d- _
:: (e.g. upx compress the output .mex)
1 X' O3 |/ I" srem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
: F# X$ i0 c. @; a6 Q, K9 n3 Qrem set POSTLINK_CMDS2=...
* E$ n; Y+ [. l. Y; s3 R+ F
" s6 ]/ k2 ?& e/ P0 D) Q:: You can change these if you really need to.0 |5 v9 ^- @7 |2 ]: }" G4 U6 H7 l
set COMPILER=g++
- z# h' E: c3 l& kset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE" q. A0 T2 \ V$ i4 n
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG) h) w6 t; M/ [% D! | r: q
set DEBUGFLAGS=-g
9 H8 c. F0 O$ ]5 U6 }9 uset NAME_OBJECT=-o
& r3 k/ a1 O/ [2 N8 k0 I% O
- L# `* C! h4 l1 h0 kset LINKER=g++0 D' x) `7 o* M2 q" W
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas5 f& d& v4 d2 z0 j# ~; Y" b
& p. _% B9 B, g8 q
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
9 j+ v+ r8 `9 ?set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
2 t# u4 j. c/ @* Z0 S. {3 B" X% o. @+ |- ^
! `9 V0 X+ t; b- u3 G:: EXAMPLES
1 x( Q8 p! f T:: ========
* a2 u, D6 u$ c3 k& v7 g4 x9 W
4 U9 @6 f$ K9 z- [ {5 c* c3 y:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use/ |( x/ S7 Z1 z* y3 Z
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
! g( W# e4 ^/ A, u% k5 u4 b5 o
; ]% W$ N( a# n M/ Z; N" R5 G:: To add include dirs, lib dirs, or compile/link flags, do:. { [/ O& X. K i
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp) y! ]" p5 I. Z! Q2 o. K( G2 t# X/ I
% }. v, w7 m5 \1 t: D# w T* F- Q: D
. U6 ~& B/ ?0 W) G2 w. N选择编译器
- E+ E: V7 g. V! H9 ?6 V8 O, B查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: / @- j7 G* a5 B, C) h% G5 n
$ l1 ]; ^ p& e. s6 q选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: & A; q* l7 _% M7 s
8 T' Q- Q( d; }8 |0 Z如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: + e1 W$ Z g8 d+ [" k" j9 E7 w0 I
$ k; [2 |: A' k0 R% E& h& v" J s- V5 W m/ r/ Q; f+ z
刚开始我也以为不能用,后来试着编译了一下,竟然可以! * C" G' S, V" m! R) Q
; [! j0 Z2 X7 M6 l
/ ~5 W) g# m' K( Q! aDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
6 x# O' x) ]' ^5 W! G- ~: L+ ]1 g/ D! e, E6 c1 p- p0 a% z
) {* |4 L+ c0 }/ X
编写c/cpp文件
r/ V0 x8 O7 V: Y- t* F+ @# ]- z) z
与普通的C文件的编写有两点不同:
7 N2 T; q5 m& V0 D2 D. T
2 r" V8 N6 l" g- R- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。( `. ~% I. X3 A: M7 F
: B1 }) m" X$ x9 H
下面以一个求和的例子说明:
1 M+ b9 j2 m B% m3 w" I$ P+ G7 O1 I5 I" @+ b
#include "mex.h" // 使用MEX文件必须包含的头文件
5 o5 z4 r; q) @// 执行具体工作的C函数2 W1 W- G, _: s& c. B
double add(double x, double y)4 {) J+ B+ Q) N7 t; {9 Q6 v4 J( ?/ \
{
$ a; p5 n' o9 r$ t; O+ G' ^ return x + y;2 R! ?* a ]/ T# k* D z0 `
}
9 Q. q& F) z' U, q( a! Y. ]8 g// MEX文件接口函数
. k" B; V$ {8 `$ T, g( Gvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
( F8 Q9 S: u6 M8 D/ e D9 H{2 B8 j) F( V5 f5 u0 S' `8 ]& y
double *z;' Y1 g. f. D! P& O' B+ i1 E
double x, y;
$ T% E3 S9 c# [9 R plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
: X1 `6 G- a' J+ y0 o5 c2 S z = mxGetPr(plhs[0]);# J s1 d0 W0 Y3 W9 |. F9 g
x = *(mxGetPr(prhs[0]));
7 v, R6 V$ h) I9 |; r y = *(mxGetPr(prhs[1]));' l8 {% m0 j/ \) k6 G
*z = add(x, y);
- n0 s7 I7 q: y" x0 H+ ?}3 b) W8 g+ k9 R
; W6 G+ P, w8 n8 H/ w! Q
0 J6 z4 e6 X/ r- e4 Q: o2 x: ]" I1 U
Matlab命令窗口输入mex add.cpp,运行结果如下图: + E* Q! T: j: W* Y4 m
4 V9 W2 M8 Y; s/ r% ?
, Y6 `1 ?# o9 |/ h9 p [& w# c在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。6 g6 _7 }3 k$ y1 P! f
+ w- v- h5 W# r" u5 l3 T; g
mexFunction函数介绍* d# }' G9 G" g- t, F
mexFunction函数接口如下:- X! P. x$ t) C! J+ F" K* n @
7 O& X. c& S! w7 d" x5 t' w1 H
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
' H( v& V+ m4 ^! @+ t2 E& K9 e
$ }: T$ @% v/ i. M* ]可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
) b8 f: ^: \; A9 }9 }+ ?( b# s5 _: [, n
3 F9 E1 H0 {" |* n9 I参数 意义 英文全称 类型! o- T6 W7 E B- y! O0 M
nlhs 左边输出参数的数目 number of left-hand side 整型(int)
# c* O" c& M) J( Qplhs 指向输出参数的指针 pointer of left-hand side 指针数组$ k7 a/ h) x9 N/ u
nrhs 右边输入参数的数目 number of right-hand side 整型(int)& I" {) B2 Q" L0 T
prhs 指向输入参数的指针 pointer of right-hand side 指针数组3 x6 s3 w) ` w* k% g
详情参考:
, u$ G1 d0 }$ C% V [, z. N4 w' j% Z' @ E
Matlab参考-MEX库9 X! L% z9 b2 s- P
# z( c& g& d8 `+ [
MATLAB中mexFunction函数的接口规范(转载)% j! v& l' ]0 z/ C/ m7 W* X
8 L! R0 q% H0 p
Matlab与C语言程序的应用编程接口
8 }: v& U- P) d- R! @9 }
/ Y& ]% D1 [, x. Y* smatlab和C/C++混合编程–Mex' }2 W7 s5 T; K7 d& B, Q5 b( o
5 `2 O& X8 \, B! ?6 \编译多个c/cpp文件1 N( u# |8 I6 o/ ?; m
假设A.c调用B.c,B.c调用C.c
# g9 q* G' c% L) `可以使用如下命令编译:
! k$ m1 ? H1 }( z9 l5 f
7 _! G4 F0 q/ f* u' e& J6 n3 |mex C.c
( o& q6 M5 q- ]( ]3 Y" Pmex B.c
% i6 }: A) d$ p$ a) e( imex A.c) Y3 X ~0 l2 ]* U
/ C. H) l6 S; ]# g: {( M
0 ~" i9 ~* S6 b, M) d/ Y或者5 F# y& h( T# i) a/ }% ^
2 e. ?( V% w0 v/ |% w4 p: n( Lmex A.c B.c C.c
D1 ?# f0 Z v9 G5 C% O; ? |
|