TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
# o# Z0 S4 g+ J, x* }说明
4 t. S" ^* r7 w* o o% O \Matlab混合编程7 d4 K. f2 c" ]) ?& M
下载与安装编译器
9 D0 {- X& T& vMicrosoft Windows SDK 71CC/ S+ @7 V0 ?6 {8 q0 n# K
TDM-GCCgccg
9 Y5 z, M1 ~, `4 y2 t! T, p' u/ x$ UFor Matlab 2015
* C8 D* J: y. D3 j2 SFor Matlab 2014, t) X4 l! v+ y$ e
选择编译器
5 m9 u% n. k) i. }8 G# K' l* P6 \编写ccpp文件
1 l* u* d2 U: g0 gmexFunction函数介绍
3 ^) ~7 p" o- B- F编译多个ccpp文件
5 V ^# A7 B; A: \2 y1 J' Q一些实例: c, q3 {/ {/ j3 e
MATLAB2015编译MeanShift
& V2 q# n' q5 j) o% @9 B! {3 ]7 XProblemSolution" |9 H; E/ j6 O& G% x( M( ^! E' G7 v- S
找不到编译器或SDK5 }- T* y4 B" O% X0 X, }
Problem
! A+ F D/ e) e) H% `/ G( V4 USolution
3 m1 `/ h/ `# @: _) l6 z注意1 W' B4 t4 E: {5 Q( K. C
error C2143 syntax error
' K' I+ h3 l; {Problem
6 X8 x! H3 z: E) PSolution
v- ]/ \. n% f+ @& N4 L一些有用的总结
7 b. r r' P6 [, M' _! R/ p注意系统平台和文件路径
5 e' E5 \# G: p: ~7 w' G& J' l运行效率对比
; z7 Y9 B* L$ o( A说明' r% s5 N3 w7 ]
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。; s$ h9 B/ l z4 N- w) t
D- [ b* f% f" P- 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)) [6 P2 Z( U3 C
: x6 O s! [+ p! R' z: z$ Z
: ?8 D# j; B& F5 L U4 m- wMatlab混合编程
0 _6 M% v% s% T7 w1 x& \* V% x# v下载与安装编译器
7 Z! ?6 \1 l/ v' E: B4 yMicrosoft Windows SDK 7.1(C/C++)9 @7 t4 L% l9 C3 [9 A- R
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
, H& }+ S8 S+ c% |& ~
u$ ^$ Q* u W* m! E- G下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
# q$ ?- d$ M% j% ^/ K- f& z! \$ ~# P: `
TDM-GCC(gcc/g++)
+ L7 {3 ]5 @4 }6 n; q% cFor Matlab 2015; e0 ?% w0 i9 F1 i# `5 t' q
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。 |' A; B Q; p" I. E& [
1 K5 Z9 d2 e8 Z$ j# i+ d; [
- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:. N$ G, C' `, C# }& h: w2 f0 ]
K0 ~4 I5 v! f" W- h- 然后,还需注意的是安装路径不能有空格;
/ h! n2 d- s6 l4 A
- p$ W: h) x5 l% L1 w- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
K) n' g: O+ r: A! \% ]. i7 F
" i3 K) D1 O o+ N( \
至此完成!$ r2 f" j3 {( P- G1 r! n0 u
* }5 x$ n4 i- i: l4 V
2 I+ x( n1 J$ I6 `" T: cFor Matlab 2014
z& q2 u+ E% }" k! L# ]1 X如下文章针对于MATLAB 2014a。9 ?7 a, R( A2 |4 r
' [( y+ y- U' |$ P2 n4 }+ O x) @: j点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。! N C2 |+ k1 D$ _, S5 |
; H' B0 i5 h. ?; ~' S7 y1 ?根据以前使用经验,安装路径最好不要有空格中文。& w' v3 t# O4 r
( z0 @2 d- P4 H
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
/ J* I2 f) M) }1 i
# x& i; g( R, M3 m1 E' I/ D
7 n) E' p$ y: k6 B. x最后的战斗:
7 g( N9 p, V* B1 i+ w因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:& `8 _% w$ ~$ x( F" L2 r
8 M) Z7 D( W) X
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。% R c9 y+ H) g& ^* {; ^( q
% }5 ?6 V6 W! q* K9 c2 B, F在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
( [8 @9 T3 I1 b \6 a- ~
" j' ]4 A; ], S7 a4 [. Y9 K%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
" G% i6 B" z5 Q$ |' y8 f
( a: K. ?3 U. v9 y* o下面是代码:
; h K/ u1 l4 o/ j: |$ o% n4 S6 S$ g
@Echo off$ q$ d4 r9 M# E4 |% N" E6 g6 t! V% x
- t6 @& s1 E2 j:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
5 V& D( a0 E8 N:: parses it and only understands a very reduced set of commands:, C2 F" `7 ]! V _
:: "set" and "rem" apparently, everything else is ignored (behaves as" l% i8 A3 k1 S
:: "rem"), so don't do any fancy batch stuff in here. There are some! g; |4 n7 v8 p% K
:: undocumented special vars you can set here that will trigger MEX/ M+ u2 S% ~" o U: o0 R
:: to do fancy stuff.1 M. y; K/ {2 Y2 u
1 N% ~4 _6 |3 h7 l: Z& r
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
% P# B. ^- o: e2 a. v7 G9 b: r:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
1 z1 F5 R# F M
7 W0 m2 [+ o' Y0 b2 b2 ~6 J) Q# u:: Tested with the following:
+ n3 K) v6 e% h& B6 q. f; g, `% Z:: 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
0 ?3 P2 P" B! F. a, }
]5 @9 F( X: k4 k; M8 Q0 }:: Set this to your Mingw64 top folder, where you extracted the above
0 S i }3 T" J# Vset MINGWPATH=p:\mingw64
/ L7 l+ C, h. X* c& ~) @$ ~$ W' C+ {: m+ w5 l
:: Leave these alone unless you know what you're doing.
1 W/ B* d. `# v# V; d- Hset PATH=%MINGWPATH%\bin;%PATH%+ `/ v5 i: q( M
set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs3 `) h1 R4 f+ i( T) D
0 l# E$ Q% W) K! z7 H3 i( b
:: You can have MEX run some commands before calling the linker.* {6 x/ b A: ?
:: The two examples below will cause gcc to output the full path to some
3 ~8 R0 p4 ~9 K; y; K# i:: static libraries so you can link statically to them (see the
* X! e, F# m( T! I+ e3 W4 A2 _:: LINGFLAGSPOST special var below). You can set any command here, however.; f" A3 T1 I) k. P9 G, h* g
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
# ]' B R: `5 b1 h, mrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs5 d/ V# E& x* i- }2 q) d$ W, y
rem set PRELINK_CMDS3=...
J4 w; `4 {2 }7 R; _- ]
3 M& G/ _, E$ b:: You can have MEX run some commands also after calling the linker4 s; k( r, @! J0 M8 ]
:: (e.g. upx compress the output .mex)) R1 y6 _, ]' a- U8 M0 r" ?
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
0 ^) O+ E# g/ a) |+ Erem set POSTLINK_CMDS2=...
3 D9 }; K+ ^' f" k/ |, u5 j
% e6 K2 K5 u6 K: ^ g* {) Q" J:: You can change these if you really need to.
# i3 T+ `) `6 C% p' `8 uset COMPILER=g++
7 f* N7 h; W9 l" r: ~6 z5 ^6 a kset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE9 T1 N4 S3 u& t$ l3 t5 Z* X
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG: W* u: F1 z0 a
set DEBUGFLAGS=-g/ |1 A v6 W+ M. X- ^2 L
set NAME_OBJECT=-o4 L- [7 A# v% N$ T
9 P/ ?0 j% [( \6 c" N+ m- |5 H
set LINKER=g++& _; f3 i- C" d/ Z* i& S" D: O% u7 t
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas. I+ y( O& w9 X: R3 ]% E3 Q8 T: a
1 @, r A1 Q2 w zset LINKFLAGSPOST=@%TEMP%\mexstaticlibs- a( l7 g! N8 z, i- y& U
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"8 D% y4 B* y4 r' }; s5 h3 J- L5 ]! V
( ^$ j( F5 a3 }3 u# j5 A
* c, t9 ~( g% N- e) y! f:: EXAMPLES
$ ]( C5 m% N" z' J1 `:: ========# ~5 z# m* z$ I1 E
( W0 Z# r* o- X" m! d- B:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use4 \. ]1 e1 j9 H5 i) @3 C
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
U1 Y& ]* F+ H, F, @0 H3 e2 x8 J9 O& s( o0 l: V/ z9 v* J
:: To add include dirs, lib dirs, or compile/link flags, do:7 c. o3 P- F r* q! M4 E( }* G
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp( t, m- ]- ~( \, N0 s. z- j( I
( ]: e7 k$ U6 m/ V m6 r* W
7 Y; R$ v& i0 M9 a
选择编译器
' y& C4 {8 N- Q& }, \. @9 K. b! W查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
l2 k3 r8 v2 |( B5 L3 c; ?. \
: O+ o4 d; B. m. |- G7 i选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
+ E; c3 w8 R; c) D, l
( U6 j i4 P# O! C' w
如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 0 A) U+ ^6 F# [- z$ W+ w3 a- B( M8 V
$ @0 n# ^/ `3 `' d+ P
$ j; _1 h$ z, T/ h刚开始我也以为不能用,后来试着编译了一下,竟然可以! / R9 [: C% x5 x3 X& M1 |8 ~0 E
Z% D( I6 m/ B9 ?
4 W9 E# w- u. M1 H. e
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!3 z5 P7 I, b7 a$ E& Z+ ~- I
p+ _) |$ e: R! _6 y
+ h0 M8 e6 T" r, k
编写c/cpp文件# d% }' P3 a _$ H3 c+ g! l) X
) X* {2 Q2 T8 }& t ]3 w与普通的C文件的编写有两点不同:% o; T( |+ |4 M* {
6 z* N! B6 f! t/ a( a- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。
1 p0 {' L- D7 a/ D$ x
! ?9 n+ n, z# W. I: Q下面以一个求和的例子说明:
+ c( F: i( U" S* Q3 z1 |: @" ?: l8 z4 V* S7 o6 p( W' j4 q
#include "mex.h" // 使用MEX文件必须包含的头文件
! k! g+ B$ S' Z4 l! S2 F( G// 执行具体工作的C函数- X; ^# I9 B, J4 r$ a
double add(double x, double y)8 ~9 }+ r% {" i9 n0 I
{
( X' D& {# M/ m return x + y;
- L/ A6 x9 O0 y+ S}
- X( H+ {0 V: ?- O, h5 Z// MEX文件接口函数3 f. P6 m1 ~7 G4 I6 S) L
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])$ G- w* ?- y' q% o. ~9 y5 u
{
, i$ n& k0 }- s% q6 c/ [) f double *z;
0 s& s/ i$ ?7 W3 o: w/ e double x, y;6 s* p5 |1 a/ y
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);: D8 U, d" h- X! w: P# S$ a
z = mxGetPr(plhs[0]);( v/ {, u0 o# k1 d6 @
x = *(mxGetPr(prhs[0]));8 I" x. S4 N |: m
y = *(mxGetPr(prhs[1]));
* L0 d2 a6 e& Z! `, s3 J3 w4 _ *z = add(x, y);
. z; W+ ^8 n% F3 a2 r}( n8 Y4 C( B5 p8 Y% q
0 \3 `6 r& }% {( ]
2 W) u2 u8 N$ RMatlab命令窗口输入mex add.cpp,运行结果如下图: 3 g" w+ d# W' M2 w! |/ Y/ M
" w! u* s! I! ~ z9 u/ E& l# @# N8 w- P4 h
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
; A) e: o" {% L. M; ~0 C
. U7 H+ q( _7 q' c/ d5 lmexFunction函数介绍
$ [# u! g* G( h6 d' H+ KmexFunction函数接口如下:' s6 V' c! V* g
1 G% n0 y X5 m( K
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])' B4 ? u; J/ Z% l; o! k
- G/ i4 |* _& g可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:0 s# x$ ?6 ?/ C$ }2 t: D
( ^4 M& S+ H6 f9 o( L参数 意义 英文全称 类型
6 M8 m8 {, Q* t& p* Ynlhs 左边输出参数的数目 number of left-hand side 整型(int)6 h9 O) B6 q2 U q2 W; k
plhs 指向输出参数的指针 pointer of left-hand side 指针数组9 u8 @8 _1 [/ p" h
nrhs 右边输入参数的数目 number of right-hand side 整型(int)0 s1 L3 ]+ m+ _/ z
prhs 指向输入参数的指针 pointer of right-hand side 指针数组
. h! {9 M, S9 n* u详情参考:5 ~, P; x* A7 d, P2 j8 ?" Q5 G
" [0 |# E: w/ VMatlab参考-MEX库- N+ l2 @. B0 I+ O0 i
+ w7 Z7 Z$ f: Y- g: g" J( L
MATLAB中mexFunction函数的接口规范(转载)
# V4 y6 H; B2 w' O+ `
7 ?: ?7 ?2 l4 |% e. W) pMatlab与C语言程序的应用编程接口
. J, b3 l5 Z2 J7 Q
: I; C5 t9 |; g Z6 _8 Xmatlab和C/C++混合编程–Mex
: z7 ~/ L4 s4 y# {2 ?6 d# {% l: C6 [* p+ k
编译多个c/cpp文件
, Y) R/ Q0 G! o* Q: v7 }假设A.c调用B.c,B.c调用C.c * }, q, L/ h; V0 z
可以使用如下命令编译:8 q% I$ s& p& h3 o# L: B
- Y4 G4 y3 ^# X3 r/ Hmex C.c
. U& h: C; O* X5 u# Y! zmex B.c
( [3 _8 F& D- Z2 r* P; c, c* Zmex A.c! v& m1 M: d4 q+ f) J/ i3 V2 y
, p9 w& m5 r* d7 z/ D
% [. P/ @- D% o
或者0 S. f: ]! v4 m: R4 u2 N* j A
2 q7 A+ u. }- V2 k! Kmex A.c B.c C.c. N$ J2 a, ]. n% ]' ~- v
|
|