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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    2 X) ~3 g4 \. y0 n4 J( ?9 `说明
    . l1 L9 P" r, AMatlab混合编程
    7 H: T& I5 W$ k1 |) n% z下载与安装编译器
    2 F+ U5 |' z2 C- JMicrosoft Windows SDK 71CC/ b# G' V" @" g1 ?3 D% H, I
    TDM-GCCgccg
    9 G  W+ X9 k# J% UFor Matlab 2015
    6 x, y) d* D* b6 ~4 @& d  jFor Matlab 2014( ~! c! v$ C& m$ G( X
    选择编译器
    + x( T. `/ w; u0 F: U  ~5 T5 ]: i编写ccpp文件% m% b/ ]+ F+ D0 y4 a
    mexFunction函数介绍9 v. n2 ~! V; m& c
    编译多个ccpp文件& Y9 q  ~: i% V/ H$ W2 C
    一些实例
    , p1 I" o: X% x/ O6 o- C" PMATLAB2015编译MeanShift" E% t$ v' x  n1 D( b
    ProblemSolution
    : _+ P. {  {# L找不到编译器或SDK
    1 z& A7 N0 R% LProblem
    5 q: P* b6 E$ r$ E$ ASolution$ m0 C1 B+ C. @% i
    注意
    7 F) j! n, ]# R# ^) L/ A$ qerror C2143 syntax error' l% m+ g4 t) H: R9 `; L
    Problem
    ; X, a6 e* q% C2 w1 i8 M8 f$ [/ TSolution
    2 s1 i# P  U8 ]/ W  N. C一些有用的总结
    6 u( y9 S- H4 I4 S/ i注意系统平台和文件路径  {9 ?* n* n9 {: L
    运行效率对比
    4 T, e0 M& p, D" W% r! O说明8 K  c4 u7 h5 P1 B6 d
    记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
    0 U' H+ j. ]% `
    $ w) ]) s! T1 e6 p* w) p$ J
    • 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)
      - n# D1 I2 C! ]5 z7 `' O9 N6 N
    $ T4 S, y1 h# x( n  I& _; B

    . Q, @' D' I9 P0 {& fMatlab混合编程
    ' O9 o+ l4 q- G  o7 }下载与安装编译器
    9 @, v/ r! m8 E. i, tMicrosoft Windows SDK 7.1(C/C++)4 p3 z. z1 \' N7 b( B2 ^
    点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
    & X! P5 _: `& k1 r9 G. S) K$ \' q, z; l
    下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    3 W7 `$ F& V  `9 P7 {" \4 X- ]
    4 g9 P+ l' N: l4 ~TDM-GCC(gcc/g++)5 D, Z" f6 `8 t1 n" ~
    For Matlab 2015
    6 \/ R, G0 r7 m# DMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
    ( J8 z' M8 |2 ~: y
    # L6 E2 w, h+ Y$ U* R% `
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
      0 u( x* R7 _, X# u3 [+ s
    0 `9 t+ p- ~7 Q" O* f
    • 然后,还需注意的是安装路径不能有空格;3 V$ x0 k2 r! D, U7 B
    + e3 W8 c. t+ c8 e" X
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:
      , _9 G% x  ^5 O" a) {" e

    : }+ d; F% ~3 \+ C; A+ e7 q至此完成!
    7 Z) f% N; i: u2 x1 E: E; W( S# O! H9 N% W+ [+ T. X# ^
    " Z  }+ D9 p' ]; y- Q& e  j
    For Matlab 2014; X. g  u# f& U& V, z4 x. ]/ d/ L) T
    如下文章针对于MATLAB 2014a。
    ' Y9 T6 z9 [# v4 i( c) D' y8 G& {: J% h% R' i# z
    点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。( W) Z/ X0 h- o. c0 ~
      s; N6 \$ R. o' ^6 F
    根据以前使用经验,安装路径最好不要有空格中文。
    0 ^' d$ M! `$ n; d# }9 _; y; [. `5 g% e4 [, O) t
    安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    % _# F( q! k% `2 F" X   c; Q- w) N% J; \
    : B0 w8 Q! L6 T. V4 \
    最后的战斗: ! P& A7 }" B1 i! g$ K$ v
    因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:6 \! }7 u' i; A  Q1 U7 j5 f/ O9 ?) _8 I
    ' ~3 l- J4 U5 `. u7 F% z
    下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。- ?0 T6 m) q$ n1 X* [1 }

    1 h: [' h- h" h- Y2 O$ t在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):, o* b! `2 g1 e4 q" w
      C5 x5 f7 L; f0 i$ L5 ~2 }
    %USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    : o- o' Z2 Y1 u& V3 P+ d
    * f- m! |; G( |- c! j% d7 g下面是代码:+ z. ]" _% o' S' K7 j& ]( \

    : |% {+ T; X* [@Echo off, Q' _( o5 R8 I5 O, ^3 u" H
    . K$ Y# G) |/ ~9 v+ o' v
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX
    6 f% V  Q# q3 z: O: p! L::       parses it and only understands a very reduced set of commands:+ C5 Q3 @9 Q5 C5 @8 Z
    ::       "set" and "rem" apparently, everything else is ignored (behaves as
      n% G; {3 s4 f& T, W* A0 M! Z: _& S# M::       "rem"), so don't do any fancy batch stuff in here. There are some
    0 i" ~1 s9 K( ~  y( W::       undocumented special vars you can set here that will trigger MEX
    - b$ h) D; f' a::       to do fancy stuff./ V$ W3 Z6 W( G2 k7 k1 R4 @

    8 F! f: l  O$ Z- o& X:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:/ z0 I+ ?/ p# I: l4 M
    :: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
    9 p5 J+ A3 w) H8 x
    1 ~8 s; i2 t) s1 ?2 h:: Tested with the following:! Z% x7 _+ \' s6 g$ D1 I
    :: 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) I/ ~/ N) l2 H4 f, f
    6 z- q7 ?1 M2 a  I+ K# L: p% Y
    :: Set this to your Mingw64 top folder, where you extracted the above6 [; t2 A3 Y4 X# o( q" Q( w/ J
    set MINGWPATH=p:\mingw64
    * M: c% U8 @/ m2 k; u& r
    * e8 k  n6 [) E% P:: Leave these alone unless you know what you're doing.1 `9 k, z  o1 ~$ H( H( _# C* @1 v* t
    set PATH=%MINGWPATH%\bin;%PATH%
    7 j6 G2 J+ o& k1 r7 iset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs  X/ @) [: @" e) V: h

    & X6 |* i) _+ \:: You can have MEX run some commands before calling the linker.
    - V" k+ x6 @# F: H6 }/ b# j:: The two examples below will cause gcc to output the full path to some
    2 a3 H$ s& e9 C# A+ }:: static libraries so you can link statically to them (see the
    - Y' Q  \7 l' A: a+ N; k" ~:: LINGFLAGSPOST special var below). You can set any command here, however.
    9 E$ X5 H4 Z( Irem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs; r5 I4 B6 _2 J2 A; D: n
    rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs$ l, D! ]- b8 K0 ~4 V8 D, u
    rem set PRELINK_CMDS3=...# A" }9 k6 a2 z8 k. A

    / n" p  I8 ]9 c6 K1 k:: You can have MEX run some commands also after calling the linker: Y7 s  P8 r/ n' X  W* H) i  d- _
    :: (e.g. upx compress the output .mex)
    1 X' O3 |/ I" srem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    : F# X$ i0 c. @; a6 Q, K9 n3 Qrem set POSTLINK_CMDS2=...
    * E$ n; Y+ [. l. Y; s3 R+ F
    " s6 ]/ k2 ?& e/ P0 D) Q:: You can change these if you really need to.0 |5 v9 ^- @7 |2 ]: }" G4 U6 H7 l
    set COMPILER=g++
    - z# h' E: c3 l& kset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE" q. A0 T2 \  V$ i4 n
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG) h) w6 t; M/ [% D! |  r: q
    set DEBUGFLAGS=-g
    9 H8 c. F0 O$ ]5 U6 }9 uset NAME_OBJECT=-o
    & r3 k/ a1 O/ [2 N8 k0 I% O
    - L# `* C! h4 l1 h0 kset LINKER=g++0 D' x) `7 o* M2 q" W
    set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas5 f& d& v4 d2 z0 j# ~; Y" b
    & p. _% B9 B, g8 q
    set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    9 j+ v+ r8 `9 ?set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    2 t# u4 j. c/ @* Z0 S. {3 B" X% o. @+ |- ^

    ! `9 V0 X+ t; b- u3 G:: EXAMPLES
    1 x( Q8 p! f  T:: ========
    * a2 u, D6 u$ c3 k& v7 g4 x9 W
    4 U9 @6 f$ K9 z- [  {5 c* c3 y:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use/ |( x/ S7 Z1 z* y3 Z
    :: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
    ! g( W# e4 ^/ A, u% k5 u4 b5 o
    ; ]% W$ N( a# n  M/ Z; N" R5 G:: To add include dirs, lib dirs, or compile/link flags, do:. {  [/ O& X. K  i
    :: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp) y! ]" p5 I. Z! Q2 o. K( G2 t# X/ I

    % }. v, w7 m5 \1 t: D# w  T* F- Q: D
    . U6 ~& B/ ?0 W) G2 w. N选择编译器
    - E+ E: V7 g. V! H9 ?6 V8 O, B查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: / @- j7 G* a5 B, C) h% G5 n

    $ l1 ]; ^  p& e. s6 q选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: & A; q* l7 _% M7 s

    8 T' Q- Q( d; }8 |0 Z如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: + e1 W$ Z  g8 d+ [" k" j9 E7 w0 I

    $ k; [2 |: A' k0 R% E& h& v" J  s- V5 W  m/ r/ Q; f+ z
    刚开始我也以为不能用,后来试着编译了一下,竟然可以! * C" G' S, V" m! R) Q
    ; [! j0 Z2 X7 M6 l

    / ~5 W) g# m' K( Q! aDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
    6 x# O' x) ]' ^5 W! G- ~: L+ ]1 g/ D! e, E6 c1 p- p0 a% z
    ) {* |4 L+ c0 }/ X
    编写c/cpp文件
      r/ V0 x8 O7 V: Y- t* F+ @# ]- z) z
    与普通的C文件的编写有两点不同:
    7 N2 T; q5 m& V0 D2 D. T
    2 r" V8 N6 l" g- R
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。( `. ~% I. X3 A: M7 F
    : B1 }) m" X$ x9 H
    下面以一个求和的例子说明:
    1 M+ b9 j2 m  B% m3 w" I$ P+ G7 O1 I5 I" @+ b
    #include "mex.h" // 使用MEX文件必须包含的头文件
    5 o5 z4 r; q) @// 执行具体工作的C函数2 W1 W- G, _: s& c. B
    double add(double x, double y)4 {) J+ B+ Q) N7 t; {9 Q6 v4 J( ?/ \
    {
    $ a; p5 n' o9 r$ t; O+ G' ^    return x + y;2 R! ?* a  ]/ T# k* D  z0 `
    }
    9 Q. q& F) z' U, q( a! Y. ]8 g// MEX文件接口函数
    . k" B; V$ {8 `$ T, g( Gvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
    ( F8 Q9 S: u6 M8 D/ e  D9 H{2 B8 j) F( V5 f5 u0 S' `8 ]& y
        double *z;' Y1 g. f. D! P& O' B+ i1 E
        double x, y;
    $ T% E3 S9 c# [9 R    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    : X1 `6 G- a' J+ y0 o5 c2 S    z = mxGetPr(plhs[0]);# J  s1 d0 W0 Y3 W9 |. F9 g
        x = *(mxGetPr(prhs[0]));
    7 v, R6 V$ h) I9 |; r    y = *(mxGetPr(prhs[1]));' l8 {% m0 j/ \) k6 G
        *z = add(x, y);
    - n0 s7 I7 q: y" x0 H+ ?}3 b) W8 g+ k9 R
    ; W6 G+ P, w8 n8 H/ w! Q
    0 J6 z4 e6 X/ r- e4 Q: o2 x: ]" I1 U
    Matlab命令窗口输入mex add.cpp,运行结果如下图: + E* Q! T: j: W* Y4 m

    4 V9 W2 M8 Y; s/ r% ?
    , Y6 `1 ?# o9 |/ h9 p  [& w# c在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。6 g6 _7 }3 k$ y1 P! f
    + w- v- h5 W# r" u5 l3 T; g
    mexFunction函数介绍* d# }' G9 G" g- t, F
    mexFunction函数接口如下:- X! P. x$ t) C! J+ F" K* n  @
    7 O& X. c& S! w7 d" x5 t' w1 H
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    ' H( v& V+ m4 ^! @+ t2 E& K9 e
    $ }: T$ @% v/ i. M* ]可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
    ) b8 f: ^: \; A9 }9 }+ ?( b# s5 _: [, n
    3 F9 E1 H0 {" |* n9 I参数        意义        英文全称        类型! o- T6 W7 E  B- y! O0 M
    nlhs        左边输出参数的数目        number of left-hand side        整型(int)
    # c* O" c& M) J( Qplhs        指向输出参数的指针        pointer of left-hand side        指针数组$ k7 a/ h) x9 N/ u
    nrhs        右边输入参数的数目        number of right-hand side        整型(int)& I" {) B2 Q" L0 T
    prhs        指向输入参数的指针        pointer of right-hand side        指针数组3 x6 s3 w) `  w* k% g
    详情参考:
    , u$ G1 d0 }$ C% V  [, z. N4 w' j% Z' @  E
    Matlab参考-MEX库9 X! L% z9 b2 s- P
    # z( c& g& d8 `+ [
    MATLAB中mexFunction函数的接口规范(转载)% j! v& l' ]0 z/ C/ m7 W* X
    8 L! R0 q% H0 p
    Matlab与C语言程序的应用编程接口
    8 }: v& U- P) d- R! @9 }
    / Y& ]% D1 [, x. Y* smatlab和C/C++混合编程–Mex' }2 W7 s5 T; K7 d& B, Q5 b( o

    5 `2 O& X8 \, B! ?6 \编译多个c/cpp文件1 N( u# |8 I6 o/ ?; m
    假设A.c调用B.c,B.c调用C.c
    # g9 q* G' c% L) `可以使用如下命令编译:
    ! k$ m1 ?  H1 }( z9 l5 f
    7 _! G4 F0 q/ f* u' e& J6 n3 |mex C.c
    ( o& q6 M5 q- ]( ]3 Y" Pmex B.c
    % i6 }: A) d$ p$ a) e( imex A.c) Y3 X  ~0 l2 ]* U

    / C. H) l6 S; ]# g: {( M
    0 ~" i9 ~* S6 b, M) d/ Y或者5 F# y& h( T# i) a/ }% ^

    2 e. ?( V% w0 v/ |% w4 p: n( Lmex A.c B.c C.c
      D1 ?# f0 Z  v9 G5 C% O; ?

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-7-21 01:12 , Processed in 0.144531 second(s), 26 queries , Gzip On.

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

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

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