TA的每日心情 | 怒 2019-11-20 15:22 |
|---|
签到天数: 2 天 [LV.1]初来乍到
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
* |$ m' _& }1 g' s( @
说明
$ H9 f u6 Z$ |: M2 \6 ]Matlab混合编程; v1 U& X' d$ g/ a/ U
下载与安装编译器
+ y* w1 p1 o$ O. y8 w7 UMicrosoft Windows SDK 71CC2 c6 s: L4 T2 u7 S' D- f
TDM-GCCgccg) z: a" z2 k/ b: ~
For Matlab 2015
& H+ t' \' M3 e0 n0 f% `* mFor Matlab 2014
8 A$ B" ~5 k; F8 [ L' L选择编译器
" i: R# u. K- t编写ccpp文件
+ B2 l' A- x2 V) Y V# TmexFunction函数介绍
( G: h1 ~$ Y' k0 z, i) H+ h. B+ x+ i编译多个ccpp文件 F" I! \/ { ^4 W' J9 W
一些实例# G: x! u- _, R$ Z
MATLAB2015编译MeanShift
8 M7 x* a4 l3 ]+ M) J, KProblemSolution
7 f0 _% e9 g! y- R6 _找不到编译器或SDK
+ X4 {3 E1 y+ Q: ?- \( dProblem: J4 M8 ^7 A. v7 P: j
Solution
0 s& M7 Y% x) J# p+ K! I+ p注意
7 U' N+ C8 Q' Q5 F- j; d) Werror C2143 syntax error1 h6 w( Z+ P2 j% u# j
Problem
8 a! D9 ^, l, tSolution
4 N' {% U2 h5 {: @, H) q8 H4 F一些有用的总结
* f0 K( z6 t1 |! c注意系统平台和文件路径
9 g- g* m' F% P9 U% _6 r4 Q运行效率对比
: ^4 K& `6 j( E# P. F) X9 p说明5 ], G7 p1 o5 L* h) u- l6 c X
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。5 N) k$ `$ [3 a" u
7 g* U( s+ w% N) H
- 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)
# P7 v) W/ R& d# }& S3 v+ W
. o3 h# M( g% ^9 N9 p
; m) m1 V% |4 S+ V0 VMatlab混合编程
% C4 L( d3 t5 T8 }下载与安装编译器* R8 ]! h8 N4 @6 l4 {
Microsoft Windows SDK 7.1(C/C++)
! w6 G6 \5 W" z6 p6 `* |, S点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
8 _& R4 S0 G Y% v, J! h8 I% K0 \/ l4 B7 S7 I; e5 g
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
/ F: [6 Z# j" m2 @' e
& j% o" T3 m- V' G# OTDM-GCC(gcc/g++)
6 z J9 q, G5 x8 T- k/ OFor Matlab 2015
. F7 N% r' H8 X! wMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
M( r5 C( R& L
7 i" _* v9 M/ Z& S$ |2 e- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
8 P. K y$ F* ]: N
; M4 t, j. I0 F9 O/ I) H- J
- 然后,还需注意的是安装路径不能有空格;
5 K) c0 R- M9 r& f: F$ E6 \5 q & l8 n" M# X9 X K h" } G1 l5 G
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
6 x- ]4 ]3 z! y% P f a, O+ r( m9 c
) y7 z* z. d. p ?1 W/ C) J
至此完成!5 r. E. Y( j* X/ o N1 ^
9 f3 H/ P: o/ k6 f3 f
+ q, J9 ? P* ?! z- xFor Matlab 20149 L! H9 _6 E( x0 [
如下文章针对于MATLAB 2014a。) e% |5 ^5 ?8 E9 o
; E8 t5 P) R1 c0 b# l1 f
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。2 E* F0 @; M5 ]5 Z5 f- y |
% i8 l' v3 N# k% F1 r
根据以前使用经验,安装路径最好不要有空格中文。
: B/ \! t8 ^7 _- t
4 n3 L/ N, Z3 ~' n+ g9 \安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
0 R1 r8 d& X6 c% _
2 |; B. a# L- O, U) Q. v
5 q5 i, L- E! T( Y; @& `
最后的战斗: + v8 f( V& ^1 C' m$ H( k
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:9 c" s' D; I: T. @7 J- r, S6 F
0 f+ K! n3 n: O2 G0 }, E2 p( A" D
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
5 z" l, x* o& _8 z. a& p% ?; ^+ Y
7 y! M2 p$ n @0 C, Z在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):2 e. d$ c$ l7 J# e
: f0 K/ U* n2 z8 a3 A: n3 m. F%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\( V- ^# Q; H v
. H& C& ^/ q. U7 W
下面是代码:
& g6 l2 ^3 h$ {
. P- G3 m. e( V k# R8 L@Echo off9 G; X& {/ }: K
: a; L R' a$ O. i
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
" O: u8 t, P9 r4 E; [4 e:: parses it and only understands a very reduced set of commands:
: p' a' L C: T:: "set" and "rem" apparently, everything else is ignored (behaves as7 e7 h& K9 k. |9 l& z5 @# E
:: "rem"), so don't do any fancy batch stuff in here. There are some, M. B* _2 v8 s
:: undocumented special vars you can set here that will trigger MEX& Z7 C3 U/ H; d
:: to do fancy stuff.
! X1 k i: ]; Z8 k0 V: [& F# A8 X# X/ r5 f# q# X
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:% s& m! j2 o7 g" o
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
1 P9 @- |% l0 d' j, ]* u9 W6 s K5 B! D1 j( N# e
:: Tested with the following:
0 \1 Y; A) g* k9 W8 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
+ y: A" s" W; ~& D' A' u
0 ]6 E2 o" n% ?# W, f+ q:: Set this to your Mingw64 top folder, where you extracted the above
5 n$ N5 b! k% j C, g0 j9 yset MINGWPATH=p:\mingw64/ K e/ T6 w+ R7 D/ N0 k3 @* r% M: M
8 A7 N" e3 Z3 _! G6 @. K:: Leave these alone unless you know what you're doing.
2 t7 r& G3 V4 v. o. w: S- ]4 k9 O3 s5 ?set PATH=%MINGWPATH%\bin;%PATH%
+ Y5 z; L3 }: }) xset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
: V# Q) R A- x* [1 t8 J
% a8 m& N' J# a X. U) z:: You can have MEX run some commands before calling the linker.+ o! s3 W5 s* `, }/ U
:: The two examples below will cause gcc to output the full path to some. a. C \5 T1 x: ^- X
:: static libraries so you can link statically to them (see the
, K3 X/ J+ I ~/ ?9 N6 O: b:: LINGFLAGSPOST special var below). You can set any command here, however.9 ^, \, ]: l9 }1 e4 y2 H5 J, v5 J, w
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs9 L; W' P7 B6 g) w0 `) n
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
7 Y$ D# h6 P3 E, X8 c' brem set PRELINK_CMDS3=...
& Z# l8 K$ v0 J
; [. Y/ W- U5 R8 W:: You can have MEX run some commands also after calling the linker
. q4 @& P3 V5 @% ]4 i. o$ c:: (e.g. upx compress the output .mex)
) ]1 J* _; ~, i8 Rrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
4 T4 T- S5 v5 hrem set POSTLINK_CMDS2=...
2 _: Y6 X+ d2 y4 W3 u/ N8 m5 O. z* Z, \# d& [8 T9 S: F+ N
:: You can change these if you really need to.5 u) {; z8 p0 q ?" \# P# z7 [
set COMPILER=g++
Z- W4 A2 u. L' sset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
3 r* a5 q- _' j- C2 iset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
# l& ~' F1 \/ G$ q9 cset DEBUGFLAGS=-g$ ~# A/ H% I+ A' v! D' `& i
set NAME_OBJECT=-o
2 @+ `. m. H7 D/ C3 Z2 B' a
8 [+ j! `( x6 w$ |8 U) h% sset LINKER=g++
# T* M$ z Q' k8 O& W# vset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas& B3 U+ K- [+ ?
, W/ B; Z* i8 U7 V3 i5 [& S2 lset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
0 S$ H( w% b5 S0 pset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
' w% o$ u+ G" e: }* h" N& [0 U2 d/ [) w/ s+ X
; u: t* S, c2 B- x3 t6 E
:: EXAMPLES9 u t }7 \" s0 \1 B
:: ========' m% k6 n" M& r8 P( b
" A4 [4 w6 C4 I" S" D) a k8 e2 J:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
7 M0 i; m2 M" ?:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
9 C; G& P5 s- P+ [. Q3 B! [6 ]1 i" o1 j" ?; g/ G4 a$ Z
:: To add include dirs, lib dirs, or compile/link flags, do:
, c/ O! M8 d6 J9 _:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
. R1 \" [( G4 |, O' l7 r0 ^7 _" Z( b4 ^! s! U1 n8 {4 j, n3 G
% r4 S. H; C: p$ `1 v9 z选择编译器
1 |7 r# D @$ ^; i( F8 q查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
9 l- _3 [; Z0 {$ A# M4 Q6 \8 k
3 J( z/ |' \8 W4 `选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 6 Q6 F$ e6 X9 g6 k9 f1 U
, z+ Z1 l) d3 {如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 1 d' S$ t7 e6 m$ C2 h6 G y8 |
" S4 b5 Q' W$ H( m( u
, t0 k, N- Q7 A l5 W' D8 B& I刚开始我也以为不能用,后来试着编译了一下,竟然可以!
7 H: m3 n3 }( Q! U1 g; o
8 h' D1 Z+ G( s( s! h, k
0 v9 y8 c5 w% d+ l! J. KDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
" T; V1 W4 [- e, }* b3 w, j) n7 w5 }# d: O
$ Z5 l( n5 N" `6 ~4 ?6 F( r编写c/cpp文件
{+ u& Z4 [* |. r" a
% w) {7 \) ?* z0 y- y与普通的C文件的编写有两点不同:% j' {/ F% P- C( r4 Z2 A
8 k( g+ X* K) l- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。. o9 P" ?. |4 O$ S* T
- b: t2 ~" S) ?/ X
下面以一个求和的例子说明:3 _: ^+ u( S5 U" b
4 ^/ J; K5 T2 C
#include "mex.h" // 使用MEX文件必须包含的头文件
/ ~; w5 P: W# t( n$ b4 _6 E1 w// 执行具体工作的C函数
6 M( A$ @) Q6 y/ W- G7 b+ V. idouble add(double x, double y)
( w5 w8 V0 D) e{& S) W4 c! J; o8 S2 h3 G& ]+ O6 Q) \
return x + y;
$ s8 n4 A3 }7 p}
: g: u: C) T* Y& Y6 {// MEX文件接口函数+ r; M5 u! x% Q( U7 I) i! t; |# s' q
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
/ ~8 ]: h, E7 S% X% N6 K3 y{
0 |! m( N# f$ i1 l0 w double *z;
- F; v# k+ y: I0 d6 }& ?, a double x, y;
, `, p, P8 G. n ~& ~8 c9 e plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
" f# y! T. l- Z: A& w5 @2 G$ p z = mxGetPr(plhs[0]);
E9 z( [) c9 v5 o4 f x = *(mxGetPr(prhs[0]));
7 t' \( v. d/ x9 Y$ w2 z y = *(mxGetPr(prhs[1]));
& V, z9 _8 k# G* F; [: D *z = add(x, y);
, O& i" B& D5 B. ~* @}
+ x$ S( z5 W' ~' ?! r+ z, L6 M3 ^+ [
3 Z+ Q/ T% v8 w8 w2 n8 S
Matlab命令窗口输入mex add.cpp,运行结果如下图:
! G1 f2 {2 e: U/ v' a& r- w/ p
) e& ^+ T2 w! ?
' ?* ~1 G( A6 o5 _/ X/ K' [
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
7 i& e5 w) i5 p
7 A* S% Z @) ~" nmexFunction函数介绍3 D7 @( `. B) V9 k6 e, H% z
mexFunction函数接口如下:3 O4 N' u1 W$ C
: [3 g& q; v3 U( M% k$ Cvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
, @; ]! q$ }) U) d: Q9 f& |/ Q$ C& [8 M# ~
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
* C6 u- K. X# _* I3 H# }4 Y5 u! i' k G+ ~2 j4 q8 i
参数 意义 英文全称 类型
) V3 m! b5 x( X2 C* u- |- X8 xnlhs 左边输出参数的数目 number of left-hand side 整型(int)
9 G3 i! d" v# x5 U8 p) Q8 Y: lplhs 指向输出参数的指针 pointer of left-hand side 指针数组
/ w6 M, j3 L6 K, vnrhs 右边输入参数的数目 number of right-hand side 整型(int)
* ]3 [3 u/ Y* e# S0 iprhs 指向输入参数的指针 pointer of right-hand side 指针数组0 m" J( n7 h$ }9 _% g5 p3 q
详情参考:
|- r* D" H6 ^3 K& a4 O1 l; V, I, l: _ D @
Matlab参考-MEX库2 }1 y# f }( N3 u; n2 R
4 }& q# O# e7 V8 ^# l* c3 h2 kMATLAB中mexFunction函数的接口规范(转载)
) {! m; Q7 C9 x8 w8 j$ p. m D4 ?8 O% N
Matlab与C语言程序的应用编程接口
4 h2 z: X2 d) @+ s
7 W7 P& `5 D. e( x: dmatlab和C/C++混合编程–Mex L* h, a! X% s/ [
0 d6 V E& w% i6 i x
编译多个c/cpp文件2 g/ w0 J* }' a, w9 d) |
假设A.c调用B.c,B.c调用C.c
1 c; D a" k2 V可以使用如下命令编译:6 |6 M$ a- o& |% p' z& {; T
' W1 A) y" a% D$ lmex C.c
3 a C3 _. e$ t3 J! N- j, C' D. Fmex B.c
0 m8 [- M/ i( @, _. H2 ^mex A.c
s* J. i4 I& z* b) Z/ R8 D
8 h4 J; \' W2 D7 a5 k: F4 k& ]7 y: q, G7 H
或者
$ q: [+ S0 ]$ G+ b0 J- y/ U+ G3 }( }$ N
mex A.c B.c C.c
" a% T8 J, k0 ], s7 w8 s. V) v/ X |
|