TA的每日心情 | 怒 2019-11-20 15:22 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
$ v& l5 c, _% K2 _" }; s& A( q
说明& C: M1 M4 ?# R& s# D
Matlab混合编程2 z, U- ] i# t7 A$ X3 O v
下载与安装编译器$ C; H$ X& C0 h d9 i
Microsoft Windows SDK 71CC$ @5 m8 u& ?) `5 Q6 q) f5 P6 F6 C
TDM-GCCgccg
5 x! _$ P! O( `; ?( l! L; y- ZFor Matlab 20150 z. T+ Y! H t
For Matlab 2014% n3 q% ?$ t% o" a+ m
选择编译器
5 T/ u$ D" p! c. ^ A; C( \编写ccpp文件* S( r4 _" ^6 X- q& @: `" D+ N
mexFunction函数介绍8 n' c/ t( P' q' U9 x
编译多个ccpp文件
/ K$ T2 U$ D z一些实例2 H5 f7 s: ]# ?! e' F1 H
MATLAB2015编译MeanShift- s. {. x7 B+ ^: E
ProblemSolution; l+ i- F; ^4 i# d) v0 |
找不到编译器或SDK( U4 p7 i& H2 N0 i2 @
Problem3 g% j6 E4 j, s; T& [, X$ X
Solution7 _1 i* f2 W! }; E1 l6 i" H- j( b
注意
) `% ]& l) g- f3 z1 U, O5 ^$ Terror C2143 syntax error! _* s! `, l+ u! ~/ [( L
Problem0 I9 z. p1 n! |( S' x2 _" X
Solution
9 W( N6 I% S6 u! [一些有用的总结
+ R( J" @7 `9 R6 p, I注意系统平台和文件路径
8 x9 ^. }* v) X- n- O! x运行效率对比
" \& d1 R5 U3 B$ J8 f5 h! L" U5 P说明# A6 X+ I9 {- K, Q, l* F
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
' m2 \; `6 {0 ]% u) j" q
7 ]7 E1 H u! L! q9 u: U! o- u- 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)
/ W* V4 G0 o6 D
+ H" v1 l* ~2 q6 I" a- x7 s% \6 F% X
Matlab混合编程
. {- Y) k: U" l; o( k/ I下载与安装编译器/ ]* d) L3 Z- }. ]' Z
Microsoft Windows SDK 7.1(C/C++)
* [) }3 K3 B" [! a点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。+ \# Z o$ T7 d6 |; z0 A9 P
- ~$ v0 c+ U6 p" r! R6 Q- A# g
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
2 H6 D1 b; p4 ? L% [
' U6 A1 k, ^: o$ GTDM-GCC(gcc/g++)- K" \; ~: U5 H3 W$ A% L" `
For Matlab 2015
4 _& O3 X( x% P" Z6 w! cMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。* M) X7 u4 ~: K6 r0 ^( d
& q# h* y& L' {) I- s- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
+ n$ e% V* } P+ y5 f4 c
; Y7 L1 _ P0 R- 然后,还需注意的是安装路径不能有空格;
" c' |2 ^8 [9 N+ P, x$ s+ C5 h! A1 L 4 E8 l5 }4 z. n
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:6 U) W, H9 Z+ V/ H8 n4 J. v
% }4 d' K0 Q% S( }6 l) `至此完成!/ D7 d! F' @9 q
1 p9 C% i% l9 H ?2 u
/ n- {2 _2 K' `For Matlab 2014- S; |. k/ B0 Z
如下文章针对于MATLAB 2014a。
! i# I5 X, T4 z& }7 F
* Q: t5 j* ^; E5 y* X点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
8 A7 E/ k: H; S9 z3 {0 f% a' I# ^3 K b* r# ~# D& R" D
根据以前使用经验,安装路径最好不要有空格中文。
* e( t7 r" V c! _# I+ V
( { |- F/ t+ N. J2 e安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
* x4 q8 k6 W4 N' [ T) q q
+ q4 t( }' u- c% r# R% y9 y( f) y1 h" V1 G1 l
最后的战斗: , C' t7 z' W+ _5 q
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:
2 n# H3 v: T7 z8 H. u) _# b1 n% T" o6 I
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
( s+ ]' ~* t' y4 M: G$ X4 T: ]) F8 R P1 y4 n- A: r( D
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
# N( t$ p8 j C! m4 u/ N8 U- K4 c; J, `$ D5 t) I5 a
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\- i+ t- F) N7 k( z3 k2 J
/ D+ e4 K2 Z/ M2 W下面是代码:, U. K4 J! q, n5 d( Q$ Z
, c' Y* U3 h$ f7 a@Echo off
, Z& W& s; ]8 Q3 ?
3 B2 K% }1 h- }0 X/ z* j- k:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
4 P! v0 F. O# Q' Y- L:: parses it and only understands a very reduced set of commands:
: ^4 q6 M* b% e2 g* H# ^, C% I1 t:: "set" and "rem" apparently, everything else is ignored (behaves as
3 a; W4 I/ m5 y* q( \:: "rem"), so don't do any fancy batch stuff in here. There are some$ T+ x( K+ Q, _6 S! u
:: undocumented special vars you can set here that will trigger MEX
8 k w- I% V6 C# }( f:: to do fancy stuff." y6 F" r* k3 r
4 n. I; j( Z" k. S# {" G* C0 I' M3 K
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
! s7 W$ V5 u1 I( U6 e& \( J:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
" n" F. P. y8 d* {* p! o# |/ r" s
& S7 e+ u( h& @:: Tested with the following:! _$ C* v+ w# M5 c5 j+ V- O& 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! G0 r7 c+ K, S8 |$ V5 c3 J7 _
$ ?# I" M# [* L% T/ K) u8 e' \; _:: Set this to your Mingw64 top folder, where you extracted the above
6 E/ J( O& Y7 t p1 wset MINGWPATH=p:\mingw64
Z. I0 C# p' r6 ]& }7 l- o5 i
& c9 o8 N* o( J6 i' X: t:: Leave these alone unless you know what you're doing.. {4 k4 o& R& i$ v- l3 q, k; `! h
set PATH=%MINGWPATH%\bin;%PATH%
; |( n, _6 j: p' L+ s Lset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs7 Q- N% D9 R3 ?7 J
- D$ R8 c# b, i( `2 g5 ~( o+ H' B:: You can have MEX run some commands before calling the linker.; ~! ~6 x; x2 @7 M; ]1 i8 }8 i
:: The two examples below will cause gcc to output the full path to some- P" V' @; f8 g
:: static libraries so you can link statically to them (see the* G' j$ O& L) g/ ] ?
:: LINGFLAGSPOST special var below). You can set any command here, however.% C7 b g% R& ^) z; l
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs! H2 L& N! i- @5 o
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
/ P/ A4 H/ O ]: h+ [rem set PRELINK_CMDS3=...
7 T* p7 D5 ?3 x N) o3 \* y( w
9 i0 J( ~ s Z; q6 q- e:: You can have MEX run some commands also after calling the linker
" p! L; V3 V: ^ R2 t( t3 s:: (e.g. upx compress the output .mex); Y' B! X& ~, \# y0 a
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
" ~+ X3 l) y, j+ O7 P Crem set POSTLINK_CMDS2=...! S9 @6 h* `/ d9 m% C0 `% F. O7 E
" w0 k) Q5 O" [/ ^' q( J% K, c
:: You can change these if you really need to.
' L- `' c3 D7 k3 N `/ V! z) Kset COMPILER=g++! y4 V+ u, Z' C7 _6 l3 a0 d' A
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
3 w: [) g+ M; f3 H, \set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG- f; t1 i) h8 q2 G- p: Q! L$ }
set DEBUGFLAGS=-g
5 p0 d5 T% y0 Y8 ?set NAME_OBJECT=-o
/ h/ ?( d. J5 ]9 J1 j2 G) i8 U* M* y# l8 D, a: d0 l
set LINKER=g++
/ v- A" O5 V5 B( y% B; m8 Aset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas4 J. O/ g- N0 X1 k( n
* s5 s" v4 ^. F8 }6 Q- k$ N; yset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
, \2 U% W& g3 q$ b. F: E8 _set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
4 ^ E7 s0 m/ H, w- T* [/ T' A/ I, B- ~9 l3 `- }0 S# H! l: _' k U" K
9 C l" a5 d* I$ A2 {:: EXAMPLES
- c! @4 p2 d4 U0 t:: ========4 d0 O& \- S/ U; N
5 k$ W$ U. d$ q3 H& x0 I) e:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
- b1 ?- d, O5 Z:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing./ ]7 G: y, F2 p0 E
^6 ~/ r3 H, J
:: To add include dirs, lib dirs, or compile/link flags, do:( W2 r0 o8 J5 z+ ]1 T
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp# g( d( k% ^" l( V% T. p
4 M/ e# p% ~. N2 @# U' V5 O# i- N- F+ F5 g# u
选择编译器
. B' U; d; k, ? R: R% ^. g查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
) A) s2 x( j6 u& ~$ }! t0 Q
: v; \+ {# m1 s5 }0 M4 I
选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: * q9 }$ Z, n; X! d) K8 Z' W
0 k A5 z% f% |
如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: - R1 {, n3 X! w& t' o
( L! S7 j/ _: s% m8 `7 b; N
, g& f. R% v7 l% k& Z& }4 v5 d刚开始我也以为不能用,后来试着编译了一下,竟然可以! + K1 d) e, j& `$ U
- d( v `0 ]6 b5 U3 O. K5 Z1 q4 G5 C, E
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
- ?/ N- w, H5 N5 J2 u& g+ W7 w
. W! Z8 F8 C# s+ b2 o4 E! i* o; n; `) p6 Y8 c- D
编写c/cpp文件
1 ^/ M# t# a6 }+ ?
% E$ L& F5 `+ Y3 V与普通的C文件的编写有两点不同:, w- U" e0 z/ m% s& _8 E. p
. _, P5 T! ]9 `: V) M4 @" P- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。2 i3 L7 P" ^* p& |% @
4 O% a" \' \1 n; C/ b: [下面以一个求和的例子说明:/ v" d. u* x9 q4 |
/ j7 e1 ?# Q8 z+ E/ e4 s#include "mex.h" // 使用MEX文件必须包含的头文件
- A. x4 m/ c1 V4 t// 执行具体工作的C函数( N! D8 H# ^' Z8 E
double add(double x, double y)" R- f7 y: u6 {5 ~! u
{+ n* w2 P- f( g9 K/ o4 ]
return x + y;
7 h( X, ]* @0 z* I}
! X) }" H. w( Q7 }( l9 p, x// MEX文件接口函数
* U2 P2 Q9 `& [' V8 K! A# l1 m8 zvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
* Q: j1 o; U) l{
! Q; ^- ~5 T/ B b @ double *z;
5 d$ k4 A, @# m" M: {3 V double x, y;
4 C. m- b# O+ p$ w plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);( t. [7 I- f8 z: J
z = mxGetPr(plhs[0]);
3 h0 f) g' u& @! f! L x = *(mxGetPr(prhs[0]));
, Y1 v- `( H/ Z; b+ Q' l, G y = *(mxGetPr(prhs[1]));
8 `' ~$ k8 G* t3 L# I6 x5 v *z = add(x, y);" Q+ t/ _$ J& E3 C2 z, `: o8 g P
}& z* r- k- A% r0 P4 \. M
' c6 i2 j& w7 l$ L3 l/ ~6 k0 S" o
Matlab命令窗口输入mex add.cpp,运行结果如下图:
9 @. B. X$ ]- e3 e# X! Y( {
% @. @ \) m( o# {
. K5 @+ t: r6 S z$ a+ A在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。8 a3 E R8 R0 j2 m& R& G% Q- ^5 [
. I& E) `$ I! H- BmexFunction函数介绍
, {! q# G( a0 U- JmexFunction函数接口如下:$ S7 ~! t, g9 q: B5 r: `1 i1 u
1 ~" K: G {' w- J" h9 \void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]), N" ?/ ^$ c- v" P! s6 H
( @" ~) ]+ _0 c. _6 b# R
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:+ W' c+ ^& `; e( `, O: R
# u7 F6 G. O4 T- X1 k$ ~
参数 意义 英文全称 类型
# h# v3 O& c0 u6 Mnlhs 左边输出参数的数目 number of left-hand side 整型(int)
+ G. Y5 j) j6 L: p4 }+ eplhs 指向输出参数的指针 pointer of left-hand side 指针数组
' Z# v3 W' n, ~. Z5 o |) J& w5 ?nrhs 右边输入参数的数目 number of right-hand side 整型(int)
* ?5 j4 M. z* o7 I2 a% Gprhs 指向输入参数的指针 pointer of right-hand side 指针数组
6 L/ m' t. Y! i; u; e详情参考:
4 Z& [% j. `3 R
/ w! E" o7 z+ I, i9 MMatlab参考-MEX库& |: {9 ^: K8 B: e4 e$ O+ o: ~/ g1 a
% Z9 ? v, }: x
MATLAB中mexFunction函数的接口规范(转载)9 G* T/ d9 b! l
+ }: w# k. Z7 r1 ]. A
Matlab与C语言程序的应用编程接口
( b' d. u% _6 o
) m6 ?* [ U: ?% l2 wmatlab和C/C++混合编程–Mex# V4 K$ w& u4 M; p( D
; o& |; M7 }& A编译多个c/cpp文件9 a; T, |/ T# X
假设A.c调用B.c,B.c调用C.c
* i Z7 e* h2 s1 Z6 m: A5 F6 o; f可以使用如下命令编译:
* n! O( Y4 I1 d4 J8 ?1 Q( l! D4 B) }9 e! r" ~) y6 c
mex C.c
: C: W1 v9 |3 ^/ a3 P0 ]mex B.c
0 d# M, l. Y+ m! o( r/ j5 |mex A.c+ b9 y& G2 H3 @/ x" @+ ^
/ i( J! T; ]' K* g3 X
# ]3 O8 a: h' I: ?$ l或者
; ~) R$ T. e9 u- B( @/ ]
" q: L1 }8 |5 ?, Dmex A.c B.c C.c
j# H3 f, z5 _# x |
|