TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
. T1 ~1 L* o2 n2 {& H1 _# z' k
说明' G% h: e3 [: ^! G$ Z a/ O ]
Matlab混合编程
' r0 o; V" ^% K, C& S! X% d/ K( k下载与安装编译器- b& p: Q7 Q0 O
Microsoft Windows SDK 71CC
0 n# i! j. W+ w3 `5 R* BTDM-GCCgccg
6 c; D" t& T; `" q3 C: K% ~" eFor Matlab 2015
5 Y; A. n5 _6 ]* _+ YFor Matlab 2014
% X6 n: k' J4 @8 \选择编译器
, J% ?( A9 g) k* p编写ccpp文件/ P" K* x" t5 g
mexFunction函数介绍
" a3 r. ^6 [4 X/ o# x编译多个ccpp文件
4 o: V! p2 v1 A5 U c1 v! y一些实例
) M' _. s, q6 Z s6 f r/ \MATLAB2015编译MeanShift: \8 z$ O& B9 D* t+ Q! H
ProblemSolution& z2 X/ u7 i1 \6 |. ~5 c) U
找不到编译器或SDK
9 {4 H' Y7 t8 eProblem8 B$ D# f+ e/ z$ P+ O' f
Solution6 B |* K O5 I" d# `0 c
注意
4 ^, n6 M. ?* ]" Xerror C2143 syntax error
/ t9 a8 i* W7 v# J1 l& Y; I! uProblem
$ s, D0 `/ Q& [- b0 rSolution1 @# M- n$ Z# ?+ k& [5 ?: b/ e
一些有用的总结! Y2 Z6 v. u( W* }) `% J
注意系统平台和文件路径
8 a- i( s. |) C8 p2 z- e5 m运行效率对比
- L) u+ r+ d- C/ R( |说明
$ Z( _" D/ P% ^: b3 V9 u6 B记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。! j8 B2 e! }- H2 g
4 d5 Q/ _" U8 k2 D; P. ?% 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)2 @5 ~& |; J1 _: U
& U8 ?" ]/ B$ G a6 `1 x
& S# K5 H q% R8 K% h% vMatlab混合编程
( y5 W& B# R: p3 `! X下载与安装编译器
/ A5 O1 V4 c7 ]2 HMicrosoft Windows SDK 7.1(C/C++)6 \! [: [* D+ ^) N$ Y6 z3 d- L: E
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。' e5 e6 v' ~) T9 t
) w* Y+ c5 q! c1 q, }2 B( p1 _- X; e下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
4 t" r! I& ?0 j7 P- q5 z
w$ K$ t0 E, H$ n; j; y& n3 {TDM-GCC(gcc/g++), `$ J# H9 ~: t1 |
For Matlab 2015
$ w8 h: X' I9 {6 oMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
) o7 p W( U5 y9 ?' Y. d" Q0 Q0 i/ u
- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
0 N( M* l2 x3 W
+ ^ H! k3 Q! O( S D e- 然后,还需注意的是安装路径不能有空格;7 T/ h; V7 `1 a0 F
, F! Y) }- q. t% e& {
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
4 p6 q" T9 M3 d; c' I
+ \; k! S1 G6 Z! r6 t" k7 j至此完成!! `3 J( }6 ^% |- w/ u' C" J B
. [9 i6 @4 O7 p& w- D; n
7 M8 a4 {9 y ]) O5 m6 n
For Matlab 2014$ t% n* ]1 K1 e& b+ ]
如下文章针对于MATLAB 2014a。
8 j0 @! {9 i) v8 ~8 R
4 T' Y+ h- a3 @7 z点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
/ S$ H8 @4 K, e* d) L& t
* a. H& S4 [7 ^ z7 F# ]3 z: \& \根据以前使用经验,安装路径最好不要有空格中文。6 J" C; t3 n6 h+ M& l
7 f& T$ `' U/ \5 Y7 Y安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: * n3 M/ g4 q6 }3 r8 S
' T! T" x* H i: ?! {/ h, |9 f a6 d9 ^# K8 P& b @9 @
最后的战斗: 8 y- ^& i/ r. y+ o
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:' v& R+ u7 J; O& q) ^
! U# ?+ K: d- @7 I6 G2 G下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。7 ~) m9 u, H: A3 h, Q2 Y. C) c! |
: S. r+ L8 ]" j* O
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):& y: s) x( ?/ e/ d8 U% {; s# y; E- P
3 L- n3 q/ h* T
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
6 N" Z- k5 ]; C$ D- H6 C# s% Q* U
下面是代码:
, S8 O4 h: P7 Z4 r5 S V0 h" e. N% {2 P# i3 \& R( l
@Echo off
1 S+ B/ }* N* F6 H5 {5 t: z6 ~7 Q0 l) j8 Q d' j+ {
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX- Z3 a1 g& U- ~8 Y5 y
:: parses it and only understands a very reduced set of commands:
& y+ c1 E+ G3 Q1 P# _6 u2 `; _$ U0 w:: "set" and "rem" apparently, everything else is ignored (behaves as
& c7 Y6 `7 n* B( l" S:: "rem"), so don't do any fancy batch stuff in here. There are some
7 j* ~6 s3 F j7 Q# y0 [+ F:: undocumented special vars you can set here that will trigger MEX& q' @. F$ b, z0 B
:: to do fancy stuff.& z6 c5 N- ]" y6 m0 m
/ `. h/ \, m, h" H( _( l
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:' V+ H% l7 t* ^: k8 C
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/& n; ^6 G) n+ o0 j" U
* F8 e# @3 _' M9 Z! k
:: Tested with the following:
% G6 Y( b) u5 x/ W) n7 q. P:: 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
E% E* ?$ y: N* [$ A' `
; p$ ~8 Y; C" C' p:: Set this to your Mingw64 top folder, where you extracted the above, }2 \- D2 Q1 r
set MINGWPATH=p:\mingw647 r! c5 Y$ n' q
$ H- w% k- X0 t5 X8 p:: Leave these alone unless you know what you're doing.
, [+ ?. C8 O' y* W( G1 Bset PATH=%MINGWPATH%\bin;%PATH%
( x7 h" H( ?1 \$ T! d5 Lset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs7 z" e* Z6 f$ v- [4 m D- }
4 B* s0 B8 V. ~7 u* a; T5 P:: You can have MEX run some commands before calling the linker.
4 R: a: B- l; _. J1 ]. h:: The two examples below will cause gcc to output the full path to some; ]2 Q! ~ F- \; i3 d1 |3 P
:: static libraries so you can link statically to them (see the# p0 m' }! v# f
:: LINGFLAGSPOST special var below). You can set any command here, however.1 l8 p! z9 `; Z# {# x& T! n: i. N' L. w
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
" J2 h' q3 K* Erem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
# C8 z( A' x( Y: z# O0 h( [rem set PRELINK_CMDS3=...
" C, B! x v/ G9 g6 J$ H% m4 J$ Q, n- p& w% ~& }
:: You can have MEX run some commands also after calling the linker; U+ j5 h( o' \7 h0 M. U' ?
:: (e.g. upx compress the output .mex)" Y- S+ v2 I7 N% h v
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
/ n# M6 {# V" {, }7 ~& Prem set POSTLINK_CMDS2=...
! H* {4 q k( S& u* @" \$ |! s U1 K3 ?2 ^! U
:: You can change these if you really need to.8 S' X5 s! y. R* ]) h4 n
set COMPILER=g++& ~# ~3 M) z+ u1 }
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE1 j6 P+ A2 p, K) f2 q! w7 s
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
0 b- O3 p& Z9 o7 E! r9 Oset DEBUGFLAGS=-g
0 A- C3 m7 K% S: P" M7 ^set NAME_OBJECT=-o
5 s7 R3 X5 l2 r' w/ `
8 o$ N l: i' [5 U0 t! aset LINKER=g++% f) t' \7 q! f% {. y% A
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas3 G6 L3 [& h5 S. g- X
2 @0 o; T, O% S/ z$ X X1 Gset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
% @5 s* n* y: O/ D2 I! I+ N$ \" |" kset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"3 |) F8 B0 S- V
9 M3 O, Q0 x/ J5 g7 \* W+ E
/ M5 S# g6 \% x" h
:: EXAMPLES* c1 M* U! E9 d7 k
:: ========
P1 x' V) O5 X* m3 n( ~5 I4 F
9 D- X# B1 X/ U0 V:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
6 a( v+ n/ ~1 _8 ?, _% r% o3 ]% T:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.4 P+ k6 T, y# F% Z& c
0 g: B# C6 g& d( V5 m7 A4 P! e
:: To add include dirs, lib dirs, or compile/link flags, do:! E% X$ ?& y1 K+ E- s$ s( W: |
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp" I1 I" k) o' j; @6 [' U
" j5 t' v5 C% |5 W; |: W6 R" j
$ v+ ]. M" o& m/ g4 ?" p选择编译器
1 B m* n; V; f: X7 W7 H查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
& P% H9 u' _1 M- q- _3 r r& F
' r* m# {) e6 j( k }; ]+ [选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
) }) D* g8 E, `& W3 q
~1 J7 T2 x# E2 _# Z
如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: . t& H! i/ ?5 t# i+ x1 A% r! [# \/ |# n
8 y" ^* l& K& @# z, m! y* H9 V Y
' K, x6 o. ^3 B8 ]3 _* U- Z$ r
刚开始我也以为不能用,后来试着编译了一下,竟然可以! " M6 t( P3 j e0 D
7 r$ z. M3 D5 ]# t! q7 G3 c e% u0 Y- f
^3 U, u2 F; B# _" U0 h6 m0 XDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
( X6 h6 k# [% M/ c5 B9 C- {' T1 V. s4 a) R' m9 _
! f" u$ [3 p2 P8 h/ z) r L编写c/cpp文件
) {' \- e% y7 |+ _6 |& v
3 v( K" F; \4 p; m( T( e* \与普通的C文件的编写有两点不同:
; H0 ^* h2 z- L# p6 R+ M$ n' ~; S9 @! n& P' R
- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。6 z/ I# w# R8 b) D
/ J3 J5 p* y9 K# A, [! U下面以一个求和的例子说明:
$ |9 m: H+ |$ s2 j2 ]
, l5 V1 ^; M# Q' L9 g6 l, [: A. b#include "mex.h" // 使用MEX文件必须包含的头文件/ d6 w+ z0 H. {
// 执行具体工作的C函数( Z( U+ r2 ^" B* x4 u7 x& k# q
double add(double x, double y)0 \ @, _+ g6 s% c; a/ j$ T6 v
{) N5 A W* p& L# x
return x + y;
, l$ {" u( e1 ? e$ p: F6 o# {}( ?. s" _8 I- Y& r
// MEX文件接口函数0 `8 }; s# d0 f; h3 B
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
" Z- ^, `! g% D/ E, O{1 r' r" q/ f% s% D/ z# p- m
double *z;2 V+ G2 l2 G1 t1 @
double x, y;
9 j3 y6 {4 o( p5 j/ q. _- o* } plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);7 [7 a: {1 O, k
z = mxGetPr(plhs[0]);
5 o# b0 a. n0 S; p9 \7 d0 m" f7 w x = *(mxGetPr(prhs[0]));
1 D4 N1 U4 H7 b: u/ X' ^ y = *(mxGetPr(prhs[1]));8 Z* I6 o. z) w2 S0 q4 f8 a
*z = add(x, y);1 d8 R+ N: Y) w3 r! P
}1 ?. ?6 x* k% O2 I2 K1 z9 f( L
/ R. p. A: ^1 G% c4 v
" n, h& ~" N! u; d$ q+ s
Matlab命令窗口输入mex add.cpp,运行结果如下图:
1 A1 r$ s# c# O: c; S
7 ` D, X/ i I a
, f. o4 r4 X( [% ]' B$ d在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。; @. v. k- m% _/ D
2 P7 b; w; F9 D4 Y: z; y' v* [5 W
mexFunction函数介绍) n% Y0 y$ {. ^
mexFunction函数接口如下:8 {- h7 a# T. Z2 ]( [4 s7 z" i3 R
1 B% S3 `1 v$ |) Q! Yvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
: d7 ]; _$ R: c' i
% M2 R* o2 \' w% a/ `& k, W可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:$ P/ h; W- G$ M* o; A
* ^" U* e, d) n/ Q" i2 b
参数 意义 英文全称 类型
: j; n+ R/ k( K& b4 {$ Rnlhs 左边输出参数的数目 number of left-hand side 整型(int)8 Q- M9 x/ ^% M; T4 x: |# b
plhs 指向输出参数的指针 pointer of left-hand side 指针数组
8 R" P8 B- e& g- qnrhs 右边输入参数的数目 number of right-hand side 整型(int)
6 q; e" V, R- ^" S7 }prhs 指向输入参数的指针 pointer of right-hand side 指针数组, F9 v6 ^! N) v7 E( G4 V/ S1 Q
详情参考:$ v$ I6 W" |+ t9 {. G, G% |, G) E& F
& @( ]7 X# {$ N7 E4 q# @1 v
Matlab参考-MEX库; d4 K( I) p/ k
# F" L$ A9 H* o* j% z }2 f# b
MATLAB中mexFunction函数的接口规范(转载)( g: N" v. ~5 g9 Y) U
8 g) Z- D" u5 s
Matlab与C语言程序的应用编程接口
! B- s# k9 Z7 R$ k Q q1 W+ q9 `. U' u6 a2 t; f
matlab和C/C++混合编程–Mex
k! ^* c2 n* a! m
7 ^$ x7 E1 L, i" c' k编译多个c/cpp文件
: w* t: u2 }% U假设A.c调用B.c,B.c调用C.c
5 T6 Q8 _- J$ S% M# l可以使用如下命令编译:
: R3 M( O; G+ ~! b# X& M# }9 r" ?& J7 s8 ?" Y
mex C.c- m3 R& z; N. j
mex B.c) F! X* h* {. a$ W4 n2 }
mex A.c
d" j) @3 j2 k, y8 `8 G# W6 q" _# g4 `, E
- P0 Q6 O; N1 ^6 c) M
或者8 A& p6 C m5 H7 I. h/ s: J
. }( W. t- f6 p$ Hmex A.c B.c C.c$ ^. T# x8 X2 M; ]0 \
|
|