TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
3 H! H$ r% w6 x% |! C说明
/ A9 v9 o* \: b6 F6 `Matlab混合编程7 Y+ j$ d0 Q5 B2 g
下载与安装编译器3 D V) l0 O; a
Microsoft Windows SDK 71CC
9 J/ z" _5 R9 J6 q1 D1 O& GTDM-GCCgccg5 F) z7 _8 C1 f
For Matlab 2015
; T) }' A1 Z6 V, Q# VFor Matlab 2014
# x# C1 G& e7 S* H+ T3 |2 s0 A选择编译器
( J' G/ ]2 m4 I x# u编写ccpp文件4 j g" N8 }. Y* ~( D1 k
mexFunction函数介绍4 ~2 A+ ]! s# E- x7 j6 C
编译多个ccpp文件
! d! b8 p2 w3 j8 ~3 m) {: |) D. h3 t一些实例
8 k Q ^8 Y- Q4 EMATLAB2015编译MeanShift4 o/ Z/ S8 ~2 I" r
ProblemSolution
9 u7 f: U' a: o% S8 f: ~, f找不到编译器或SDK6 s/ u% y) B, g2 v' L
Problem
; Q. R# K% e. b+ u: h% ~# P% m' _Solution: Y4 z& a( t2 \
注意+ \, ]( b( I1 h& u( j H( _9 I
error C2143 syntax error
5 i0 K& `) e9 Z, _' v6 v bProblem8 F7 v/ I8 c; k3 j
Solution
5 J5 E3 f* s+ d" h一些有用的总结
, k7 l- T& E3 l0 x1 G( M注意系统平台和文件路径
& h6 A% B. [3 r. ^3 l1 r运行效率对比
3 K* J$ K+ C- c t$ B0 T说明
# A9 K* l9 G9 V; T# m" i( z记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
4 t3 @) O" R7 t) z- r; h" p* v4 {; z/ w( v
- 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)
. r8 E) `- r, y, N I3 k
" p1 v" k( ]8 m' _1 O
9 n0 \2 b* _/ W) u' WMatlab混合编程
% ]# s7 `: y' U l/ Y, l3 ?, z下载与安装编译器; x7 I! v: J% M+ b9 ?+ t+ q {1 Y( V
Microsoft Windows SDK 7.1(C/C++)6 Y3 S- b; d* Q" l L$ {
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
1 x" E4 n8 b$ k# ~$ @% @, ]5 B4 S* {. X6 n" a: `; U# T
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。! D( K3 @' w; Z: K4 G( Q
9 N) G9 N; ?0 E: S' aTDM-GCC(gcc/g++)
8 ?0 ]5 K) Z5 p* g& x l3 n; KFor Matlab 2015
" L8 ]0 W V! ~& F6 g! p% HMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
" U, v3 U' I, b3 ~. K4 q) c8 H/ v) y) j' [- {* P
- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
& m0 T9 l# Z! e, w/ W2 O) Z, X
* ]- ~* m/ Y# t6 s( n
- 然后,还需注意的是安装路径不能有空格;4 M# ?) s' o" }# a' m t5 r/ P
' Q: ?1 O; G( R, Y, \' L. r% o- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
( q! I3 ^5 d$ r Y$ K
& A, s5 G9 Q1 D# x# K5 q至此完成!) J7 ?$ p: p; t9 `
$ p; V9 q0 ~% L7 L* Q7 Z
9 A3 v6 D- n N( Y! X2 W" PFor Matlab 2014; L# l# Z" a1 i# X) A/ x
如下文章针对于MATLAB 2014a。
5 r1 J0 ~, I: c2 M- n0 s
* b. b- P- Z8 ]3 o* O点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。: M; _4 \" F$ S" N, Q$ V8 J
4 C9 q/ u" B& Q Y根据以前使用经验,安装路径最好不要有空格中文。7 ~ o! C' B" ?! I1 e
! Z% l8 n* l3 V7 L
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
7 q7 j3 }8 T: ^& k' N) e3 d5 S4 N
3 H- ^1 u) _8 F1 k8 T( u) r3 f# ]+ c+ t8 m
最后的战斗:
* E: [0 m' |; S: E; z1 O' `因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:* M' H/ A5 y! p8 y4 @
+ J& A4 a" @! }. B0 B# }# J下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
1 e: l. @5 D8 a0 L% V T8 O& e4 B2 v2 r4 a {1 L% T* s" a F+ o
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
4 _* S5 [2 f+ {7 z* j5 X+ @, D5 m, Y' U- k7 [ V1 }- R3 c3 v! z
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
! M# y! W1 b: S: n4 m& O
2 \+ c5 N. j1 g$ Z9 f下面是代码:, ]$ a3 ?0 E O9 C V8 D
0 T. U: d$ s+ ^, |& Q@Echo off
. l ]1 H8 X5 _; _
% p3 T% `2 J/ l9 N- N6 Y:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
, H9 B3 r; u0 F, q& s:: parses it and only understands a very reduced set of commands:; w9 `1 q+ [! ~9 ]
:: "set" and "rem" apparently, everything else is ignored (behaves as
) U: c' U+ z) u1 [# o4 r9 o:: "rem"), so don't do any fancy batch stuff in here. There are some. x/ x0 C! K7 {3 E, E$ |9 h
:: undocumented special vars you can set here that will trigger MEX
6 {: m- N/ ?6 q9 S- j8 r:: to do fancy stuff.- R& d' b/ b8 Q+ i) f0 @" M8 J
9 J3 ?+ {& _' g z8 J% k
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
" T5 M9 a- G3 _% {! y. K. q8 \:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
, g* b% _6 T: w& A0 J* `5 [& @% Z0 \
:: Tested with the following:8 O/ q7 W: Y) Q# ^% @* m. U& K) ]
:: 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.7z3 O0 a) u) X% j& _% ?
" N U& C7 Y: p! v; {& P- D
:: Set this to your Mingw64 top folder, where you extracted the above/ @5 X! r" v% C) k# F, r
set MINGWPATH=p:\mingw645 z7 M1 t) ~' l/ k0 f- H% r& B
; @9 q/ ^- _4 o- V& w7 [, \% L:: Leave these alone unless you know what you're doing.
* j3 `) d6 z" w3 `set PATH=%MINGWPATH%\bin;%PATH%; o6 u5 A: u+ G# j4 Z$ q
set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
: e1 X: j( U5 ?4 F" k% o" E8 \* [& k( v2 Y0 X% j @
:: You can have MEX run some commands before calling the linker.; O, z# c* Z" {$ D
:: The two examples below will cause gcc to output the full path to some5 ]1 p& V1 H. \; B* `
:: static libraries so you can link statically to them (see the6 f) E; r0 ?0 l5 W4 d. R0 U
:: LINGFLAGSPOST special var below). You can set any command here, however.
+ D& v) f* e! J2 V1 b' ?/ Hrem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
) J, G3 z/ k* j) E0 srem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs B% D$ \0 [: }4 I& E y
rem set PRELINK_CMDS3=...
, `, }* }$ Q1 k0 C, K- Q7 \
( a5 Y N0 a* u; C& L% ~6 }' s1 R:: You can have MEX run some commands also after calling the linker
- ~$ h5 v3 b7 {7 y. f:: (e.g. upx compress the output .mex); @3 ~1 B7 p' l
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
5 ~6 n9 r) `8 f; `5 w' Trem set POSTLINK_CMDS2=...
9 ]6 \$ [4 m" u, B1 T1 K9 Z0 J* T# L& o
:: You can change these if you really need to.. G% [5 Y: u' D4 |6 N* ?$ i
set COMPILER=g++
& h% f7 |" h7 }: ]set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
- \# Z- h: q" F/ J# zset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG8 u! Y+ a9 R6 `
set DEBUGFLAGS=-g
6 u @" J9 R+ C4 Hset NAME_OBJECT=-o
; I% E9 W/ o0 z( ]. Z' n' Z
- e# C% K: q& Y ]; |% Mset LINKER=g++$ T! c, G+ m! z; u8 C
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
# y9 x8 o' T& ~0 E5 R" h
( |9 s' P5 ~' O9 Tset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
2 O$ e0 e, S j( m( f. i% C& gset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"; _, o0 O! d+ r
6 I* V! [' H, e9 c3 w0 _; x" s& d/ ~0 |6 j
:: EXAMPLES) A2 Y0 w H0 G7 q. j. l& \- J! i
:: ========
( p' T% h' ?% O8 K+ [- I6 f
2 ]% w. B4 Z/ T. S3 n' I:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use0 c1 \& p( o. m: `
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.4 H' Z% E, I9 d& e, u, S. A( f
9 k* Z2 s8 K0 ]# c" t6 i3 o; d:: To add include dirs, lib dirs, or compile/link flags, do:. ^. Z9 |7 h, E/ x) j9 e
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp' M1 y [' o5 w1 r& F
& J( w; v5 s) V6 o- _$ {' Z+ N/ m3 Z; R
选择编译器
L: @8 L+ d5 L( o4 C# k: ~# U& v9 W查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: # m' E+ s8 ^. ~* I
5 }4 D9 ~' c$ H; H* A7 R/ ]选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: ! I! ]1 l! c- @) H
$ I% @, _/ p. u7 b* W如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: ) D4 i2 j& H$ }1 H2 b1 J+ H- U9 x
! i3 K5 ? H1 g: O8 W X
2 L, h% S7 e( v8 ~0 n1 C. v' R刚开始我也以为不能用,后来试着编译了一下,竟然可以!
7 {0 V' q% s" t6 }* O
3 Y+ U; |- ]) i
1 M# w& O' O" i E9 G0 JDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!3 z. n& n& @5 ^& g
' Q4 t" r) R: M& v4 m/ J! l# U2 {5 o1 M, o; E, O: j2 v. a4 [* L: a5 |
编写c/cpp文件/ R5 K6 x% J+ L( O* @
% Q& ?8 }6 j7 P T5 ~
与普通的C文件的编写有两点不同:
( ?* f0 |" `2 X' X" | O3 H/ L6 ]0 e- E- M7 H
- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。! Q! K4 m/ d$ t& {
4 `" u: X& P6 o. f9 M% F* Z下面以一个求和的例子说明:
0 S) j- ^9 G5 j' [' E4 M6 k/ }% W
#include "mex.h" // 使用MEX文件必须包含的头文件
! N' f3 ^7 k/ W3 s1 y; J// 执行具体工作的C函数
3 M/ @2 Z8 z% S, jdouble add(double x, double y)
( c1 k1 ~( o y0 B# Z* T{
$ z0 q' w- e: \/ u2 f" C' g return x + y;
; g* T6 w: G0 ~3 T( q. J5 W}
/ _: I4 d9 e" c$ i# P, o; g// MEX文件接口函数* B, V. V- q1 A8 _% j% t
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
: [% p3 y- |9 q3 O% V/ G( t{
1 v; g9 ~( X2 B3 _# S: O' V- C double *z;
' c! s. N3 H6 Z# ^! q2 v double x, y;
8 Z8 ]* C/ r1 H I1 ~9 p4 b plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);' T0 A, S" t! Y' }* S, q% a
z = mxGetPr(plhs[0]);( a4 H0 S5 |' u
x = *(mxGetPr(prhs[0]));
+ z6 o" m9 B" B* h y = *(mxGetPr(prhs[1]));3 t2 e8 d7 ~4 B
*z = add(x, y);
s- b: S' y( h# y8 d/ [}1 ~8 w1 l4 W: y, P# l
8 _ B* z4 d5 D* {4 K' ]# m4 c/ B& J! i% i" X# i
Matlab命令窗口输入mex add.cpp,运行结果如下图: ' ~3 P% l) M# i
$ }: }7 X9 w" x. n. K& u* e# J
3 Z6 p& M6 y6 b0 Z* r) T3 r5 V在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
: t! E( J9 H" b% F* N& o
% [& ]. I4 \) S" O1 emexFunction函数介绍% h0 {% _6 f; N% }+ h" _! |4 r/ g
mexFunction函数接口如下:9 o/ Y8 K& ?; G+ [+ p0 w9 W b
* c0 _, I% t4 E& i7 s* W$ L. Uvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
0 v( J4 b& ]. O, ?0 x B4 C8 A0 m( {: E- @7 k4 |: x& K" {5 ?8 P
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
/ A S1 [! D. X; P$ P
' d: h/ T8 h) u8 H3 k3 u! B* P1 q6 o参数 意义 英文全称 类型2 V+ r* N2 N8 r8 E; O
nlhs 左边输出参数的数目 number of left-hand side 整型(int)/ u S. m, `- g6 d
plhs 指向输出参数的指针 pointer of left-hand side 指针数组
% i1 l% J7 W: }+ nnrhs 右边输入参数的数目 number of right-hand side 整型(int)! Y `+ w: z- s' W6 X
prhs 指向输入参数的指针 pointer of right-hand side 指针数组, {$ {, V. ]! b9 A8 L9 N
详情参考:
" w; p( k! c5 J3 e9 ] J @) b# i. y% y5 V: s/ T. x1 u
Matlab参考-MEX库" h2 v* K8 T. m7 l
+ Q1 j7 x7 P, u% t( j- q& TMATLAB中mexFunction函数的接口规范(转载)
$ P, R' P5 z2 N0 V
8 M( r9 D: _& D. y' Y- kMatlab与C语言程序的应用编程接口; Q' q4 H7 Y$ m- h$ f& x
9 P- V q: w; m- Xmatlab和C/C++混合编程–Mex
# ]- w' }* W% {& w8 _! f7 n# ~( O/ F9 m/ E$ u: \) x' W) y) L; [, C/ i& M
编译多个c/cpp文件( Z+ T) G4 }( a* O p
假设A.c调用B.c,B.c调用C.c # F6 U3 U& {4 Z! ^5 Y2 E6 t' B
可以使用如下命令编译:5 i" T6 @6 J- K$ o0 n9 G) f
) Y5 `( S0 ~/ f6 ?9 V
mex C.c1 g! {0 p6 U, \" K
mex B.c9 O3 W) }! i2 T
mex A.c
5 D% q7 f/ M; V+ |8 E- A
/ S) u' S: d% ]) B, q) V# D( F! k' t5 Y( M% d5 ^* d: X4 i8 D8 {
或者 q! t8 m/ B5 h( g9 U+ _
8 N9 D+ T) Y( |- [, T0 j$ O1 H8 Omex A.c B.c C.c9 e( s, P- P3 u) P
|
|