EDA365电子论坛网

标题: Windows 64 + Matlab 64 MEX混合编程 [打印本页]

作者: mutougeda    时间: 2021-1-21 10:03
标题: Windows 64 + Matlab 64 MEX混合编程

% W" I/ A! I% s/ ~. q说明0 ^# P/ s9 ?6 r; g9 T0 U
Matlab混合编程0 o0 w% [& o3 N% O2 ^" c- N
下载与安装编译器
# T3 f. @" _( J% Y$ Y, g9 ]Microsoft Windows SDK 71CC/ L4 J; h; I3 A" V4 U1 Y+ F7 x
TDM-GCCgccg* P1 Q5 b& A. J- ?! q% d% d8 I
For Matlab 2015
, b8 L" X! H) R) e0 n$ IFor Matlab 20149 ~) u$ N$ V8 H0 ]7 R$ \8 ^: z
选择编译器  G7 b3 ^  K4 T# C% D
编写ccpp文件
+ c. e; L$ U' SmexFunction函数介绍
) Q: g0 A  M8 o' G  D编译多个ccpp文件/ j! ~0 R" |% |- x% S
一些实例. ^9 F/ G4 u7 L. A7 B2 G
MATLAB2015编译MeanShift
+ D( C0 Q/ z* e' {' kProblemSolution6 F0 H$ T' t; j4 x  k* A0 x
找不到编译器或SDK& R  S- Y9 Z1 q9 f% ~1 L# G
Problem+ V- q  e; O; [2 K1 P
Solution5 A- S3 z* s# b
注意
; _$ u: x/ E5 Z' A* Nerror C2143 syntax error
6 x: l& c$ ?  m% a8 T( E7 }/ D0 pProblem' I1 `% ?: u: l( w3 M! e2 i$ i
Solution7 t$ H% s7 x% g6 }2 k
一些有用的总结
0 l$ n3 r. s0 p& [注意系统平台和文件路径2 M* b8 X$ V9 |# \7 i, D
运行效率对比2 M$ v: w! p$ B+ _
说明
1 K5 M: O2 L# A* w& f. `记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。* L. l5 D' p' D; J% E* R' V' e$ @
  I) }4 w$ }/ z0 A/ J( U$ \

  O+ ?. ^5 v4 p) I1 k) |2 e4 T5 T' L1 v- n, y
Matlab混合编程( \+ L, z' J" {4 Z: V! u
下载与安装编译器
  W5 B# S9 [; r# e4 v, ]* _) x6 Q5 N4 |Microsoft Windows SDK 7.1(C/C++)
- t# v% Z. a: s2 h3 o点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。! L5 Z$ Y# V' Q/ K. y

6 _" ]; v0 K9 P) G下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
1 R+ K# D; Y1 J( B1 A  Y! I7 a7 Q9 q% @
5 f) }' n1 e( x7 g" ATDM-GCC(gcc/g++)! m& Q) a9 `# |  b5 n& C' E
For Matlab 2015
+ g- P$ B) N. u' GMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。4 \( A8 |1 |$ p2 D
/ n, M6 E- Z* b$ z- Y, s& {

7 w/ n% y. G& }$ Y
0 B( C/ Z6 y  y5 B( ]
4 G+ H7 R& [$ u6 V5 M" ?至此完成!
* G2 z: d  c+ a/ E3 `1 E9 f# v6 H; A
/ D" P' S+ E: m6 r4 _) ]8 V( F& Q1 k1 Q% M( u. ~$ k% K
For Matlab 2014+ x% |9 p+ K) b- ^  I2 ?
如下文章针对于MATLAB 2014a。% @8 V9 O) W) ~8 ~
- h1 x/ L/ [/ `) I1 Y7 U
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。4 @6 M# ]! y$ F7 i7 Q5 `
8 I3 I! x$ p9 y* F
根据以前使用经验,安装路径最好不要有空格中文。2 Z  Q# E2 {% h* T% Z8 b/ C
% K/ J# r; k$ N/ H
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
, u1 u) n% r5 J 2 F+ Y+ S; p; _+ j2 ~" l3 D. g! q% w1 u

% w9 e' y# @, L- l3 ^, U# {最后的战斗:
, d! l- a" r$ J0 V4 J+ {因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:8 @) s' h+ w2 u4 h6 B. y* W6 P

" t5 b7 W0 W* j% x, s, F! z2 v下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
2 G; \, i2 }4 e! l1 a8 O3 O* `
$ E- Z$ ]8 G; _9 B5 s在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):( C4 v& X+ @/ ?# l
, V" y1 R+ i+ t/ V4 m
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
: a! i! w+ V2 P" s1 k. I3 H8 ~3 r" G1 Z7 r$ Q6 Y. N: v
下面是代码:
! u3 A/ _5 t3 G. g
( ]0 s4 [3 Q) v@Echo off5 r) U6 ~, Y: ~* i6 M  O
4 a5 [+ }$ u: N9 x' Z
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
3 K* q8 X3 _6 y! f; X1 z::       parses it and only understands a very reduced set of commands:6 A! }/ `* @) x. ?( w# |2 _) Z. C
::       "set" and "rem" apparently, everything else is ignored (behaves as
/ Q8 q$ ^* u; W( M' ?::       "rem"), so don't do any fancy batch stuff in here. There are some' h+ ?6 ?/ w8 g( q: n% L0 ^
::       undocumented special vars you can set here that will trigger MEX/ b* S5 a0 K5 m3 y; Z
::       to do fancy stuff.
8 ?2 C! y, o2 a- B% U* }, I/ N) g% N7 ~3 x; V( x
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:+ B4 k$ |" c! m' X% C
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/. j, x2 D* V; b
' C0 B7 a4 U7 I1 \
:: Tested with the following:; D) i6 G7 r2 O- }, }# 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.7z
1 L3 R' f' j' z9 c2 \
/ ], J* N5 ~  r3 `1 P* ~:: Set this to your Mingw64 top folder, where you extracted the above, s9 t& S: P) _2 o
set MINGWPATH=p:\mingw64
( x% [) u- _8 Q  _: n. x
: B6 ~6 V4 D. l# O% ?3 q:: Leave these alone unless you know what you're doing.
! U6 G+ _# z% w  oset PATH=%MINGWPATH%\bin;%PATH%
: R1 }: G. p( C1 {- }set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs; {& j; n  k7 I7 `% ]( A- J

, U$ ~- E9 c& D* _* s3 [2 Y- ?; f:: You can have MEX run some commands before calling the linker.
& _# o  S: W2 A6 H( s" J" {1 [:: The two examples below will cause gcc to output the full path to some
/ s* A( B& r  D. J2 j:: static libraries so you can link statically to them (see the: {5 D9 c$ x# f6 n# c' W1 b/ I, b
:: LINGFLAGSPOST special var below). You can set any command here, however.
4 g% I% u$ D; e. krem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs0 @% q5 s* U/ _
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs! f& {% d! u% p! Y  c
rem set PRELINK_CMDS3=...
+ W( g- o3 n* ]! c7 S& G5 m  m
* z0 A$ p) k, k:: You can have MEX run some commands also after calling the linker5 {4 z# q1 O( A8 K* _, R. T
:: (e.g. upx compress the output .mex)
& h& T$ Q' N+ z( ^  L; F# Vrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
" o$ j$ B- D% K  w- srem set POSTLINK_CMDS2=...1 c2 y7 x9 Y. u9 n! O( D

; ]6 ^7 a+ M/ Y( w& F:: You can change these if you really need to.1 }( J  V% |2 D7 n  V
set COMPILER=g++5 u, h/ J6 H, X* E. L1 C9 u
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
) f$ [$ ~( F! p& l% Aset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG1 T; U. s7 m  I+ J. \+ O
set DEBUGFLAGS=-g, Z0 T: T4 T" s, I
set NAME_OBJECT=-o
* D0 _. R' y8 {) @& P6 A; e$ R/ M4 _
set LINKER=g++# u+ C  @) h% q$ B2 }
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
6 \+ j# F+ ^3 Z: z0 p' A  X: _& @  L7 |/ {9 [1 C& _9 W8 G; o
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
6 N' K4 ~7 W4 q$ \$ E! W$ D' [set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
, Q1 m, r+ {4 @; b& e! ^/ u1 t' F- K; h3 Z7 n9 H8 ~4 c7 n7 p

8 ]% b1 j) k; J* q7 L  J:: EXAMPLES
6 b: i8 S1 L# d1 [* C# g& z: M# Q, v5 c:: ========4 D0 g: {" Y# b; p" B* W
6 f5 m/ b( P4 V5 D* @8 B8 A8 V
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use; A- ]2 g% ^* G  M
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.) R& M- {( `( W" Z* B0 Q( ]

/ W8 c. h' }3 s( |$ \:: To add include dirs, lib dirs, or compile/link flags, do:
' t, A% C: j4 W4 ~' v2 `+ w' b, s:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
  I: ?8 t  i$ y# \8 {
$ w3 B: P: J; U0 Q1 b' N# _0 n
6 w* ?4 C" X* _6 d选择编译器
- n" ^  a0 W* W; H查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
2 M# z) v7 j4 O* w$ j, z" V 4 o8 @- W- A; a3 _7 _
选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: / k% l& L6 B! R( d4 t# V1 T$ D" Z+ J

! {  G1 w2 }. A- g4 u如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: - U9 N/ h8 z# ]5 U
" t8 n" O! D+ _1 n( t3 Z) J7 U! Y

: z' p. c, `2 D! f0 r刚开始我也以为不能用,后来试着编译了一下,竟然可以! 3 p1 `5 f* \( x, N- y. ^
3 A  b% `6 v1 m1 d: B; Y1 K% n
- i3 G3 A- m2 t. ?8 |  a- P$ Y
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!  @# _; G+ e: m4 ^1 h

& Z7 {5 O$ _) S% |
7 n3 c( d1 N3 U: {& r. N" q) q9 |+ D编写c/cpp文件
+ C" G/ r$ M+ A' x' E' C$ x, l* L  \. b  b
与普通的C文件的编写有两点不同:
/ K8 c' E" e( G: i% j# \3 v
* E: |: `7 Z9 n5 m5 h2 S$ y0 n; ~3 `9 |
下面以一个求和的例子说明:
# O/ w, e" `% e$ _0 \; o" ]! g) ?- \. R9 G% E$ [1 @7 b
#include "mex.h" // 使用MEX文件必须包含的头文件
8 M$ b: m' O& \* O// 执行具体工作的C函数
, O, n( s3 g8 q1 X8 E% J$ q! C/ udouble add(double x, double y)
; j1 |- [$ D5 j7 k3 K/ O  n{
5 L% G* Y- v$ e8 n) q    return x + y;0 v2 `6 ~2 d' o9 s# p( i3 h% F
}
, d( A" B/ d9 |: W  {+ G// MEX文件接口函数. s1 s- s1 H) y1 t3 f' z1 ]; Z. n
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
) ]' Y8 [5 o8 Y9 O  x{  s2 h# i! N0 D
    double *z;
! X$ P  @- N5 c  V1 i# ^7 }& E3 F    double x, y;
' c8 H. ^& [9 r    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);0 q  m& l9 h# b9 ]) e
    z = mxGetPr(plhs[0]);
4 D7 W9 P3 i8 u  ~; p) c( l    x = *(mxGetPr(prhs[0]));6 [8 w% A$ `4 H9 u( [, n% ^
    y = *(mxGetPr(prhs[1]));
5 M5 [! F! N) F/ i    *z = add(x, y);
1 H: S) M* V, o0 c7 c' h0 n. v5 y}' a$ b5 w) X! @- X0 P2 @% g

) i  F* g: E9 p5 S
5 N* Y7 X7 D" m0 IMatlab命令窗口输入mex add.cpp,运行结果如下图:
, z5 p! y* g; J* o3 W$ Z! [0 J   T( K8 q. k/ S( H  [/ d" o
4 G! x6 M" a* ^5 r* y# H) H
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。8 u2 L+ k& K" d0 K+ L8 l6 D

3 C' M/ Q3 s& wmexFunction函数介绍  V2 w) o% t4 z3 _- D
mexFunction函数接口如下:3 L3 l: e3 {! o& T2 e" B, w

8 m7 m+ @$ S9 J2 @( ^% \void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
9 x- [' u0 w+ ~1 n. I+ w3 H: V3 q1 f- e! Q8 w% K0 U
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
2 ?1 \9 m1 y$ P, @0 Y$ u$ u- Y6 O7 V- g1 b) V/ A1 J/ Y/ Y5 z6 g
参数        意义        英文全称        类型
7 u# F" M8 i# K1 s- ]; n5 Hnlhs        左边输出参数的数目        number of left-hand side        整型(int). H2 J" P4 O1 V; ]
plhs        指向输出参数的指针        pointer of left-hand side        指针数组
1 o# K5 D6 a# z7 Q, a& |nrhs        右边输入参数的数目        number of right-hand side        整型(int)
$ Y% S& f: B" B9 q+ E0 h+ Xprhs        指向输入参数的指针        pointer of right-hand side        指针数组
$ a% U) T& l: P% \% y, u5 n详情参考:0 t; Z! r" k4 x* O; i
/ d9 H( p2 F3 b  w" R) g8 p- ?
Matlab参考-MEX库
1 P' J7 Q5 O# j2 p3 B- T  ?  ^# G) u2 ]# r) L8 M7 R+ q! L1 P
MATLAB中mexFunction函数的接口规范(转载)
0 o$ K4 v. @" ~% z1 y& u7 V
) O% d' _  l: n  O2 CMatlab与C语言程序的应用编程接口; A$ G% x& R6 q7 }

+ p( t5 T0 d5 j! ~matlab和C/C++混合编程–Mex# J: p) l4 z" h/ q0 K
9 N: C% l4 o; U& o: b5 T5 s
编译多个c/cpp文件! S  s6 u7 }3 v; r7 Z$ I
假设A.c调用B.c,B.c调用C.c
/ d. F* ?% }9 y5 d5 M4 b8 s可以使用如下命令编译:
7 j+ Q1 B9 p- t1 e2 Q
% d% R, H$ j' Hmex C.c4 Z8 h% j3 Q+ x* t
mex B.c
8 d; t: u/ r  p5 i; a9 Lmex A.c
1 @2 o7 [, z! \  i' [3 h' [, e9 n6 W$ n: S

8 Z0 [1 j* y# P2 W8 D8 F或者7 t' Q" c) n( j* o: ], |  {- m
8 M$ \/ U& X' @8 C
mex A.c B.c C.c' u$ H8 Q: S7 p5 U

作者: youOK    时间: 2021-1-21 11:12
Windows 64 + Matlab 64 MEX混合编程




欢迎光临 EDA365电子论坛网 (https://bbs.eda365.com/) Powered by Discuz! X3.2