找回密码
 注册
关于网站域名变更的通知
查看: 394|回复: 1
打印 上一主题 下一主题

Windows 64 + Matlab 64 MEX混合编程

[复制链接]
  • TA的每日心情

    2019-11-20 15:22
  • 签到天数: 2 天

    [LV.1]初来乍到

    跳转到指定楼层
    1#
    发表于 2021-1-21 10:03 | 只看该作者 |只看大图 回帖奖励 |倒序浏览 |阅读模式

    EDA365欢迎您登录!

    您需要 登录 才可以下载或查看,没有帐号?注册

    x
    9 C* c% {7 S& x9 ?9 r5 b
    说明
    : @% O; n: o( C3 H1 O7 UMatlab混合编程
    . `0 X) F( P6 Q& |; u  A6 y下载与安装编译器5 ^# D. t& j. T9 ?
    Microsoft Windows SDK 71CC
    % U7 a6 H4 B7 Q# k" W& X- P$ R0 c9 RTDM-GCCgccg* r' h1 `; S. J
    For Matlab 2015
    # r4 z0 W/ ]2 F: \. j- }1 z4 \For Matlab 2014: x7 F, g* f$ H$ [( p3 @
    选择编译器
    9 P, C; b% t9 g2 K编写ccpp文件" }$ u1 S& \$ w7 c
    mexFunction函数介绍
    3 W2 g# i8 Y4 l& }9 q5 i* t8 }8 @8 j2 X编译多个ccpp文件1 Q1 ?3 J, q) |3 k1 D1 f/ i( ]* t9 _) o$ H
    一些实例1 P+ F% H& D# ~1 g9 E# X
    MATLAB2015编译MeanShift
    % q( D) K6 N: M0 A0 H0 yProblemSolution
    6 o9 T9 {0 {1 [找不到编译器或SDK
    ) h7 @) h9 r# D! q$ Y2 f+ aProblem
    6 l+ J2 ~" l+ R4 W% ]Solution  H5 R! a/ O" i
    注意
    ! p$ B) L8 A# ^: eerror C2143 syntax error
    4 o! F* p8 Q" F! y9 R+ i0 d& y  B- OProblem
    & \9 u8 T& a* ^! l! ?+ ?Solution
    7 r* g& `0 ~7 [6 Q0 L一些有用的总结% r  b) Y7 S& l
    注意系统平台和文件路径* P* V5 P" ^" q- z
    运行效率对比
    0 S/ P/ ]- L( [5 T% d说明
    + q- J; g( H! C9 W& Y1 ~记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。# }+ A+ B$ T. ~) d8 G
    ; F* I7 v6 {8 ^: r$ m3 I/ |
    • 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)! L$ t% M! ?# O$ O% X

    : Y7 Q4 N* F1 e
    4 X, G; r1 U3 j$ T  Z/ q3 ]Matlab混合编程
    & G$ t* E3 K+ k; Q( q下载与安装编译器
    , v) P( W4 M8 [Microsoft Windows SDK 7.1(C/C++)
    5 h% a+ M6 |8 A# l点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。7 g7 p% F6 l% ?" W3 I1 d, C
    / X! R1 q! U# L) `0 M
    下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。" D, ?: J* f; m4 Q( T$ b% R
    1 i5 O" o5 N0 H  g+ ]' j
    TDM-GCC(gcc/g++). ^5 R8 S2 M% J  R2 k
    For Matlab 2015
    & s* y3 k- i; P' J% e9 IMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
    . t- u1 ?2 `8 z, ~
    ) i' s3 S& z. b& h, F5 p1 q
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:' K* `0 n3 S8 t2 {' g- ~

    / W$ S2 }' }$ g. F
    • 然后,还需注意的是安装路径不能有空格;
      6 I/ E- G7 W% N  z! f

    / i( L1 y. ~5 ?& j. W1 X
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:& Q9 S5 z& J! Q* e( D( F

    3 _) p# r% Q+ r* z至此完成!% a" @1 e- L% g

    " L. h1 L9 Y; W) W; C
    / O& X' K& w! s4 Q1 j$ XFor Matlab 2014
    2 e/ x) P7 a# G0 B! t" Q+ H如下文章针对于MATLAB 2014a。4 ?$ G) S7 M. [1 S8 R8 A
    & O9 ~) [" r) j- M. d* p  S
    点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。% C; A+ z+ f) |" n6 j" |

    * s1 @; A' U  {8 M- t2 ?  ^根据以前使用经验,安装路径最好不要有空格中文。4 ]# x4 s! Y  A3 _' G
    2 p( C, D/ U' H1 `5 B
    安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: ! A* |2 V- H% j

    5 s7 x5 U  c" H* C$ x7 I
    , {/ o- h- Y9 K& ?最后的战斗:
    . U6 l. ]' X1 Y$ b, P+ `! }/ [因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:$ e, K6 P9 B) s- ]3 u- {' ?

    ! P  |+ O) c0 a% `- b$ @- j下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。" }2 \# u! E% c7 t
    ! }& Y! F9 J4 t$ i/ _
    在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
    8 h( e- [& {" ^. X  k, M! V6 L  Y, Y$ e0 R6 J5 Q
    %USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    7 \1 g# ^; Z1 [1 R5 t- B7 L% i
    0 |: ~, z3 a1 }( \9 r下面是代码:  G/ e6 _0 M9 m/ H8 T: v1 a. K

    $ r0 N" U/ N2 m3 `' Y@Echo off
    7 }/ v$ _/ X, c( c% L1 p4 K4 r. w% Y) o* h- O! }
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX
    + K/ v. ^! z; P1 M6 P# U::       parses it and only understands a very reduced set of commands:
    6 t9 u# w7 P5 t* W! P7 N; Y: [: X::       "set" and "rem" apparently, everything else is ignored (behaves as% y: L1 U3 Q- K! w! u& f/ W
    ::       "rem"), so don't do any fancy batch stuff in here. There are some
    7 i" q8 W; Y0 p3 }( u5 d) {+ F::       undocumented special vars you can set here that will trigger MEX
    8 M, Q( G4 I# X* w" Q% p& y" I::       to do fancy stuff.. @- N, a- i9 R7 D
    ! `0 `* K8 P3 R/ N
    :: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
    + }' Q6 Y/ m* Z  ^:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/( Y: a. L! H# f! Q& h- Y: v( u

    - r& C2 u) f  r( E:: Tested with the following:6 R: h+ Z8 h* i4 k. z8 \8 c; p! x
    :: 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  l/ W0 P8 W7 k, s& P8 c# p# @$ o
    / Y: k) q- c& G& v- z
    :: Set this to your Mingw64 top folder, where you extracted the above; k6 T# \; n6 [/ H) r) P; e9 A
    set MINGWPATH=p:\mingw648 J: k$ ~$ h; C( K; |- z
    8 v. o6 l" D  b' V
    :: Leave these alone unless you know what you're doing.
    9 H) E) |& e. b0 B- Q" U2 wset PATH=%MINGWPATH%\bin;%PATH%
    1 U, t. n0 ^7 v3 x. Pset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs6 L5 c; Y; k# Y% C/ Q1 ?1 W; ~

    + K+ g) Q+ x. v, r+ |8 k0 }; b  R:: You can have MEX run some commands before calling the linker.. T% f" |9 n$ Y$ w0 V. H# T% n
    :: The two examples below will cause gcc to output the full path to some
    0 N7 O3 y3 ^; y: Q3 F:: static libraries so you can link statically to them (see the; g3 q% d* G7 j: n* D
    :: LINGFLAGSPOST special var below). You can set any command here, however.
    - c% G% v: m& e0 o; K& P1 Erem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
    " U; @" b; R! K; {) \rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs3 M; u% r1 K) n
    rem set PRELINK_CMDS3=...
    ' ^; `5 G/ Z7 \$ Y! a. c) ]7 E4 s" `  ?3 a; E7 a, b6 Q4 U
    :: You can have MEX run some commands also after calling the linker
    % M3 y/ b" {6 v) z7 \:: (e.g. upx compress the output .mex)
    * m% e9 C; l7 W6 |" l6 g" @1 m. e8 Rrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"5 m2 G5 H1 {% ~. b. V* b% `+ x
    rem set POSTLINK_CMDS2=.../ H) S& H, s6 q# @1 Z& w3 X
    ' |7 }7 K- R+ c
    :: You can change these if you really need to.' K, t$ g5 f: Y4 F& X5 @
    set COMPILER=g++3 n) m* F2 t; y7 i5 Z  t
    set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE' Z3 z$ c5 c8 o1 L
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG* F" z7 T) A" }" h
    set DEBUGFLAGS=-g( y& y, v8 ?* q  H& {# k6 j2 m
    set NAME_OBJECT=-o
    5 b7 @5 E4 }: w
    4 G- c6 L! m* Gset LINKER=g++
    " y3 w3 o7 t7 Wset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
      s; u2 b" P* X
    : a9 {: s  f% z2 aset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    $ r8 [1 F3 X2 M7 m- z, bset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"3 m8 n' B! [, [5 O6 W0 S" u

    4 N0 P; n/ {% Z0 q2 v! \- l" L( L6 }9 ]: q$ i+ t3 k
    :: EXAMPLES
    $ G# O' Z1 N: q' Q* Y% b:: ========0 q; H7 V7 D6 G" y! t  q9 m: U

    : T  D8 Q3 u4 s6 Z% A:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
    7 J5 i$ D; R) a! e:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
    ; Q$ x' ~9 e$ p3 [- B0 U5 L7 x7 m+ q
    :: To add include dirs, lib dirs, or compile/link flags, do:
    % a7 U0 g$ S: J/ s:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
    / Q, n2 V4 J& r" I
    / K# b* Q+ q+ Q# k
    ; {5 u0 I3 g. g% C: ?选择编译器
    / l4 V# D, v- t查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    : b' S! n% F$ P2 n* R5 b 4 i8 s2 j+ h1 x0 q( c, H
    选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 2 N& E& |/ Z/ w  C5 d
    5 m( x' n5 O- `" M
    如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: . Y5 m1 J8 n) ]& Y$ Q+ g1 B
    2 h! c/ H) l/ F9 k; `
    # a! p8 K' ~- R+ C
    刚开始我也以为不能用,后来试着编译了一下,竟然可以!
    ) Y# J, v3 y3 a4 o9 V* m0 t0 [
    8 ~' D( x5 l0 X' E/ F' `8 a
    # U& C# b; m) K" Y% ?2 sDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
    + h& G# _/ ?% k) A' j2 X" D! N; c
    8 l, }3 l' q" r
    , P" E9 H/ {; o. A1 x$ F4 `; A编写c/cpp文件
    9 M# R' G$ }1 e6 l1 d4 m% L5 i  x, q7 p. F; ~  Z/ t
    与普通的C文件的编写有两点不同:
    + I, P1 x  K. M. G
    ' ]1 y, c) o) r( d) ^
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。
      8 b# }) l, N1 B8 N+ S8 b4 w
    . Q: X+ R$ v* m' l" x3 f- y# y
    下面以一个求和的例子说明:
    : e) F7 {, L. ?4 U1 j+ E4 k' U/ F9 u* K+ m" ]- r1 f7 T3 h
    #include "mex.h" // 使用MEX文件必须包含的头文件
    $ ~+ `( W* b/ ]- D0 g, l) M" j: j8 p// 执行具体工作的C函数
    5 K" U; z; b- e  ^9 }- rdouble add(double x, double y)
      p5 _% Z8 g$ z5 q0 A7 q# _{2 Z  R' z( ~# k; c
        return x + y;1 }! A) M( b9 A: T: i2 Q
    }- v( P+ y. |; i
    // MEX文件接口函数2 c# {7 X- n* \
    void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])/ _6 p7 C; m% y. T
    {
    3 |/ X0 p/ v4 E8 L8 i    double *z;
    3 C! T1 i7 S: e& x1 Z    double x, y;
    8 ^& ~, s* D( E    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    3 i. [! K9 ~) ?. G  F' J    z = mxGetPr(plhs[0]);
    % R4 n1 I( A/ }6 [, ^    x = *(mxGetPr(prhs[0]));) ], O2 `; h; P& ]) y( S6 j4 j
        y = *(mxGetPr(prhs[1]));, s% h9 _% p5 J3 t, D
        *z = add(x, y);
    & E4 \# w$ c, ^5 ~5 I+ r9 f}
    ' I& a* G. N9 o8 W: o# [
    , @% |9 c. P/ J9 E
    ' W0 }! X5 E# h6 U. _Matlab命令窗口输入mex add.cpp,运行结果如下图: 2 I/ M& E& Z3 j9 Z  u

    ) T) L. |' l& q  c6 n4 _2 ]" `; A
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。% I8 u0 M9 y" Q2 S4 V/ X: K8 J4 X
    . H2 k$ v* H3 q5 y$ O  s6 S
    mexFunction函数介绍
      q7 p( d5 r( q9 M+ gmexFunction函数接口如下:, v. N7 \0 q( y

    , P# [2 ]3 q: F+ }: }7 L. W  W. W0 Dvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])* |/ C5 o8 q$ N. j  P) ~' k

    - {0 e$ a3 H/ H; S! L可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
    1 h) I9 Y/ F6 ~5 ]# R/ N! ?& @2 w7 y6 _  S
    参数        意义        英文全称        类型5 B: S0 [* i$ s
    nlhs        左边输出参数的数目        number of left-hand side        整型(int)+ G" `3 O- f- l8 ?' F
    plhs        指向输出参数的指针        pointer of left-hand side        指针数组; g6 `2 m: H% R- z1 J
    nrhs        右边输入参数的数目        number of right-hand side        整型(int)
    ' l* j8 w0 `# }9 Q9 L8 xprhs        指向输入参数的指针        pointer of right-hand side        指针数组
    : h& t: q# d3 ?& A1 G* }8 P- W详情参考:
    8 U+ f' y2 t4 N9 p5 i" p/ M0 k: C2 n& E9 e. o4 L% x* O& h5 c' l& E
    Matlab参考-MEX库) y4 L: T1 ]0 v: e8 ]/ Z
    6 x( y! h) P9 K7 E7 ?4 J
    MATLAB中mexFunction函数的接口规范(转载). c7 C  L0 L. k7 K: D& X4 b

    ) X; `: i2 m5 G! n1 c5 j( YMatlab与C语言程序的应用编程接口
    * F7 r! Y2 u0 Y+ w( H( ~* h' p" l1 |- s2 D: ]
    matlab和C/C++混合编程–Mex
    % c/ M# p7 y! N6 l& v* K% \
    1 c0 r# B6 p0 q- y$ `编译多个c/cpp文件2 e& z  O# _0 f
    假设A.c调用B.c,B.c调用C.c
    9 S1 S/ W! |4 M- {4 @可以使用如下命令编译:
    9 A; G& e5 J. S& k7 _
    7 _3 v7 _% c9 g% o% Q& Umex C.c
    3 @" O9 u* }6 n/ f- r; I* m) amex B.c9 t, F3 D; K: l
    mex A.c
    : O3 @) H; t' B$ w, C  \
    ' O; v1 M6 m) D! w$ O1 D. G4 W
      {8 w8 W( M# I6 x或者0 x$ I: V) I7 h# ?

    ) ~* T& b2 S) K. Umex A.c B.c C.c/ X- L0 D& c! M, |

    该用户从未签到

    2#
    发表于 2021-1-21 11:12 | 只看该作者
    Windows 64 + Matlab 64 MEX混合编程
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

    推荐内容上一条 /1 下一条

    EDA365公众号

    关于我们|手机版|EDA365电子论坛网 ( 粤ICP备18020198号-1 )

    GMT+8, 2025-6-20 08:25 , Processed in 0.093750 second(s), 26 queries , Gzip On.

    深圳市墨知创新科技有限公司

    地址:深圳市南山区科技生态园2栋A座805 电话:19926409050

    快速回复 返回顶部 返回列表