TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
( p/ x! A% B5 ]& x4 W! ?说明- K* B5 [- ^- `$ h, q) f- ?
Matlab混合编程
' [2 Y- v: E; J2 k1 ]- s$ t9 }下载与安装编译器
: T2 _' Y/ v2 T7 u1 N. GMicrosoft Windows SDK 71CC3 h/ R0 ~& a& Q9 m2 y5 P* {: f
TDM-GCCgccg
% y$ J/ N( K5 w9 j3 i; U/ [* G h! BFor Matlab 2015
" }0 w* T8 D) [9 @For Matlab 20144 ?/ v: v% Z: Q% H$ `
选择编译器
: Z$ _* e$ \2 }! [* K编写ccpp文件
) ^0 `5 y5 b ?7 F" imexFunction函数介绍* T8 p7 q8 t+ d5 v2 U: Z
编译多个ccpp文件) Y' m( ~ \# }* h, X" G
一些实例
% R6 u& @7 i7 y$ pMATLAB2015编译MeanShift
2 D8 _5 X; A0 U/ [! R& Y5 tProblemSolution
" p: ]7 J3 m! ] G& t }6 L9 f找不到编译器或SDK
' V3 d2 ^! L3 Q$ g3 D" sProblem. ]* p* O9 K' ?) ?9 [+ V8 ~& l
Solution
6 D+ K" ]( h1 j注意1 Y" w. K7 K0 X1 e% a) @& m
error C2143 syntax error
5 r u* ~$ P3 {! DProblem
( v- y/ Z/ ]8 QSolution) s+ S) ~3 ^6 h+ [
一些有用的总结
+ N4 H) q" k& q6 ]注意系统平台和文件路径" h9 D3 B2 K( j: D6 P
运行效率对比1 C0 O, X9 Q' E- h( B' n r* k* V7 x* {
说明! ^7 i# @: N1 E
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。, k; F* K& [- r; b, y' E
3 s! G$ j! q/ p7 J& P, H: A
- 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)3 Z+ j) H9 X. X1 A/ W$ B
. W. v) _- ]. c2 H6 C! ~
/ s, D0 a, k: i0 NMatlab混合编程
; M" C2 \; p& `下载与安装编译器
^4 Q' z1 z, q5 TMicrosoft Windows SDK 7.1(C/C++)) t2 c v% m: _1 y
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
3 X2 w: J2 }2 ]: { I. x4 v |! E" t- ]
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
0 M. f' A l' o; `4 @& Q. b0 ~$ N" u9 Z: I x7 g( z* ]
TDM-GCC(gcc/g++)# t* U3 t( j. J3 q2 ?/ {: I: _$ L
For Matlab 20151 Y1 J# h# p9 n- u& Z- e9 ^
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
% l. g4 [& K. G% R8 e0 n# k' l6 |5 R! z5 v+ Z. ^- [* |& ?. h
- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
2 G9 |6 _) p" s% _1 [+ d; }9 l- U$ [
! Y& R) `5 Y$ j* t' a- O& g- b
- 然后,还需注意的是安装路径不能有空格;
2 h B( @6 ?. m o( G3 d+ ~ G, y& ?
2 p+ U% h7 L9 S; q+ G P- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示: M" U+ N" W `- J8 X5 q" h2 I6 l
0 u* Y& n5 G6 f3 u" w q至此完成!
" f% O c+ ~7 d+ J9 W$ ]! a" l$ U4 W; M0 \& m, l9 f
$ b6 r. e4 G1 R2 tFor Matlab 20145 w/ ^8 K) t( w5 ?
如下文章针对于MATLAB 2014a。+ N9 y' h- b7 {) G: e$ A. x
5 M3 X2 C& Q* U6 T% p8 l& b; H0 I) V点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。5 B9 o% k' L4 N+ V" @: d7 e- m
( R* \% D! l9 o+ U5 ]
根据以前使用经验,安装路径最好不要有空格中文。/ ]+ W, E6 b4 [9 A: H2 \6 U" x# j" o
* F& p6 l5 q7 D" ~) _; M安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
& }7 F; }' c' \% B# J8 O( k9 O
( D! ]- E* y: m' v) c9 D' d- K- w7 u2 b
最后的战斗: , w' v( M9 g4 ]5 z3 |
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:& z4 M& j) H) _) y) @
- ~8 k' C' I- ]9 U- m$ k! U3 B下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
6 T* y4 r) Y' J8 }' x& E
8 E I& j% P+ C' L W+ W在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
1 s! N, X d' I- I) B: @# u; k) t. r0 `; i: }
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
1 ?6 M" K) r# l% B' b. T, P/ F
下面是代码:, b8 W* b8 `! ^( R
+ y1 G+ J9 A- N# @+ A@Echo off
0 ^; t2 q2 o! z Q. N! {; X. {- p E9 w
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX5 c" f+ D2 t9 o
:: parses it and only understands a very reduced set of commands:
: E( \7 {0 s, Q: G:: "set" and "rem" apparently, everything else is ignored (behaves as1 O: ?) P; ]% ~6 L
:: "rem"), so don't do any fancy batch stuff in here. There are some( f$ X/ [) R+ i3 s; o0 x) p
:: undocumented special vars you can set here that will trigger MEX
7 F: W5 Y6 Y2 [# b: W:: to do fancy stuff., V1 Z, F( r7 k. _
1 t, m/ _7 g+ x' Q# O" W0 @. w) t:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:! v5 o; n6 t0 ~ H: y! ^; `! ]
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
- _3 v( K0 j- l! z' U/ e+ K `/ o% h7 j6 U" ?) z; a' t
:: Tested with the following:
, r5 T% q/ a( C: T8 t:: 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
' V% d* y2 A# [) F, s2 V5 s, n$ X; t7 {7 P# K
:: Set this to your Mingw64 top folder, where you extracted the above0 q: q T/ Y" r, }! l7 t
set MINGWPATH=p:\mingw64
8 _! c b3 @1 ` r7 ?4 U2 R& W6 \. D) T9 Q8 N9 N0 N' T5 z! e# \6 L
:: Leave these alone unless you know what you're doing.( d9 E; N' } u G3 O
set PATH=%MINGWPATH%\bin;%PATH%
! O6 N1 p4 V; c( F; O5 X$ ^/ I* ]set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs7 e1 x' B6 ?, p: ?7 f
; z; L2 v2 d* P& w$ {+ \
:: You can have MEX run some commands before calling the linker.4 A' U/ U2 k" B& r) }4 s( a
:: The two examples below will cause gcc to output the full path to some
2 o: _0 R: v& w6 L( n" d:: static libraries so you can link statically to them (see the
6 F/ f# ^. W* M( g5 t( t:: LINGFLAGSPOST special var below). You can set any command here, however.4 i: V1 h1 P+ y* `- O
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
+ k- S& h6 q1 _% v- Xrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs- E: h3 I4 |! Y g8 A
rem set PRELINK_CMDS3=...
7 o( \+ V3 V; B9 D D0 A
+ u1 F; T, C0 u. J9 R:: You can have MEX run some commands also after calling the linker- |9 u9 m0 W% C* [1 |9 U: `
:: (e.g. upx compress the output .mex). z% X# i6 k6 ^1 q- b: c
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
8 ^0 N: F- Z# G( N+ t6 Jrem set POSTLINK_CMDS2=...
: I1 {7 ?8 r% d, W* K4 P: K$ z i5 s3 R
:: You can change these if you really need to.
7 B7 D! o. {$ aset COMPILER=g++0 e) U. h. z1 x; p3 E: r$ C
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
! h8 `" ?5 [: z- Y, I% pset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
+ v3 x% f, n6 F8 j/ M" P) Sset DEBUGFLAGS=-g
% ]% \0 t7 r% d/ c. f% nset NAME_OBJECT=-o/ R$ Z9 v" \0 x: ?8 Z* \# M% Z: W
* q% d4 |' w8 q% ]5 t
set LINKER=g++
0 f& ? R: l9 R& U; [' k$ Pset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas- }% i5 z/ O2 E& B& \( _
6 N/ P! S- v6 o6 i7 W
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
! X$ r% G5 O- ]set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
6 G+ J s9 g/ w/ s4 i$ F: L5 |' b$ M
! B, T" u( D; c" g:: EXAMPLES6 I0 Y: ]0 b4 h0 X1 S: G) Z
:: ========- {0 G% J( y6 d5 m
) B& u9 [, J3 R' C1 A3 P, e, f% d" x:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
. P! Y- T, E. w) d* o- h4 D5 W:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.3 z, @$ |/ |2 W
. r1 Z, g- A- J9 a5 z8 n
:: To add include dirs, lib dirs, or compile/link flags, do:1 i. r; h0 h1 B
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp# X, p1 U9 f+ Y
) [* M; K9 w- }, E9 Z- D s5 Z$ x
$ ?& ]8 k; h4 ]% s2 \& ~2 ~% m( D
选择编译器
* G7 r( ~6 B# L2 `查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
, R8 t- E/ ^& |# N/ ?1 Q P t
& L- i- V' ? g$ @- ~选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
9 w% {1 E1 d. v* h3 J
2 g% `, @2 I4 t0 F如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
; M/ t% M0 u& X
4 g& k) r7 f3 ]+ X8 A7 E' g+ L" E
9 u. V7 J9 ^' O" A+ w4 W4 o0 @: j刚开始我也以为不能用,后来试着编译了一下,竟然可以!
- d/ V' ?$ x+ s: L" f
, B$ n. v9 U- H5 Z% R% d( {( j/ _, ]- s9 N( R
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦! @# N: w6 g+ Q3 p
, h" T3 i T) U! V$ b, h" I R9 ?* T5 g1 Z
编写c/cpp文件7 D. @9 z6 R+ @* X% q
0 n/ _ H' `( E
与普通的C文件的编写有两点不同:
1 g& l9 Q+ L. B& H0 ?# K8 q1 I/ V2 u" d& h2 u
- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。 D( A% @( B* {" q
$ I- H/ M8 d0 n9 w/ x* v& x( ?
下面以一个求和的例子说明:7 x& m% b( @3 V. b( A: I6 s
9 O/ x; p) I+ R. a' _) t
#include "mex.h" // 使用MEX文件必须包含的头文件7 ?9 H. A, V* I
// 执行具体工作的C函数
/ g4 v. r e, N5 i4 Gdouble add(double x, double y)
9 X& J$ `' D1 a# Z# E4 W# q{) q+ Y5 ]2 ]/ M
return x + y;( Y1 f k' j [% D& G/ J
}# O. n" f( ~$ K. x
// MEX文件接口函数
) t. _* q- a }4 O; Kvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])4 [3 D8 d; s7 l( u0 d% Q7 {
{2 s3 N& }7 S! W8 Z3 e6 c; k r
double *z;
/ L1 U0 @: [- U2 j; ~ double x, y;
; t' j# r0 p# K8 \3 A) c' |# s8 ] plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);% |0 M% z6 j9 `. ]! M, i) v
z = mxGetPr(plhs[0]);! I0 Q! m0 X$ H3 B
x = *(mxGetPr(prhs[0]));7 T _% x6 R$ i2 H. w9 d3 l" W$ L1 o
y = *(mxGetPr(prhs[1]));
) r. y! E) E: I) A4 F( k0 g4 e *z = add(x, y);
I2 H8 j; `8 Y9 n}5 [; s( [" y' S" D& K9 u- P: H
$ n7 M/ D" X8 |% k; F- V8 q. c; ^, J# M; V
Matlab命令窗口输入mex add.cpp,运行结果如下图:
/ L6 p# b% @; i \- n3 ?
5 S$ l2 c2 b' a5 W9 ^% _3 o3 y9 L( y; l' o/ A1 b
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。( P' ]2 w) a9 P( ~
# n& h( F9 I" t7 e; {mexFunction函数介绍
- i9 U( Z$ K/ @# a& _mexFunction函数接口如下:- g# l5 ?; C: a
! o( _$ b7 J- {
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
9 \6 }: f, d7 W2 K- j) G7 A/ {2 r; O' H7 ?8 [( u5 E
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
) |: O5 M3 L3 k+ q" D3 n# ]) g5 e" x) x
参数 意义 英文全称 类型
- i( A' _* {1 W1 f* I5 R! Lnlhs 左边输出参数的数目 number of left-hand side 整型(int)( L' b. b& j2 J% k1 q* \- e
plhs 指向输出参数的指针 pointer of left-hand side 指针数组
( _) q3 j! Y5 n, Xnrhs 右边输入参数的数目 number of right-hand side 整型(int)( k; _( m8 l' k
prhs 指向输入参数的指针 pointer of right-hand side 指针数组
5 Y6 f7 u) ^ j; T详情参考:
, H) v; X% y# D. a3 O
3 d9 f4 i4 ^5 fMatlab参考-MEX库
3 ^" J3 t- O B) g# A T
" R" W4 r: p! f) h( H3 A/ }& YMATLAB中mexFunction函数的接口规范(转载)
* L+ p ^8 R& M8 W5 p# S
. _% K8 v9 B! }% R! H( TMatlab与C语言程序的应用编程接口
* e/ f. `$ e* `0 y& V
' W: s3 L. D, l% Bmatlab和C/C++混合编程–Mex
$ u. z, Y; D6 W$ c) g! K* M5 o3 n: Y
编译多个c/cpp文件
7 U# @, @0 ^0 r: H5 E假设A.c调用B.c,B.c调用C.c
/ ] D: b2 }* M- k. L; ?可以使用如下命令编译:0 |2 l$ A: ?0 E7 [# H
& Q* m9 Q; q: a% z1 E0 f" rmex C.c
1 K8 S/ u2 ^! @: M( } amex B.c* Q9 @$ W2 e/ y
mex A.c6 O6 j. U6 I! T* Z
' g& [" y% X" N
2 \/ L. Q: H0 Y, M6 n/ S! \或者
$ h1 p' Y' G$ J! \' Y I: }8 p
4 V, D6 ]# k5 I7 @4 m& zmex A.c B.c C.c3 r" b }! b" k9 Y7 ~9 k( H
|
|