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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    # o# Z0 S4 g+ J, x* }说明
    4 t. S" ^* r7 w* o  o% O  \Matlab混合编程7 d4 K. f2 c" ]) ?& M
    下载与安装编译器
    9 D0 {- X& T& vMicrosoft Windows SDK 71CC/ S+ @7 V0 ?6 {8 q0 n# K
    TDM-GCCgccg
    9 Y5 z, M1 ~, `4 y2 t! T, p' u/ x$ UFor Matlab 2015
    * C8 D* J: y. D3 j2 SFor Matlab 2014, t) X4 l! v+ y$ e
    选择编译器
    5 m9 u% n. k) i. }8 G# K' l* P6 \编写ccpp文件
    1 l* u* d2 U: g0 gmexFunction函数介绍
    3 ^) ~7 p" o- B- F编译多个ccpp文件
    5 V  ^# A7 B; A: \2 y1 J' Q一些实例: c, q3 {/ {/ j3 e
    MATLAB2015编译MeanShift
    & V2 q# n' q5 j) o% @9 B! {3 ]7 XProblemSolution" |9 H; E/ j6 O& G% x( M( ^! E' G7 v- S
    找不到编译器或SDK5 }- T* y4 B" O% X0 X, }
    Problem
    ! A+ F  D/ e) e) H% `/ G( V4 USolution
    3 m1 `/ h/ `# @: _) l6 z注意1 W' B4 t4 E: {5 Q( K. C
    error C2143 syntax error
    ' K' I+ h3 l; {Problem
    6 X8 x! H3 z: E) PSolution
      v- ]/ \. n% f+ @& N4 L一些有用的总结
    7 b. r  r' P6 [, M' _! R/ p注意系统平台和文件路径
    5 e' E5 \# G: p: ~7 w' G& J' l运行效率对比
    ; z7 Y9 B* L$ o( A说明' r% s5 N3 w7 ]
    记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。; s$ h9 B/ l  z4 N- w) t

      D- [  b* f% f" P
    • 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)) [6 P2 Z( U3 C
    : x6 O  s! [+ p! R' z: z$ Z

    : ?8 D# j; B& F5 L  U4 m- wMatlab混合编程
    0 _6 M% v% s% T7 w1 x& \* V% x# v下载与安装编译器
    7 Z! ?6 \1 l/ v' E: B4 yMicrosoft Windows SDK 7.1(C/C++)9 @7 t4 L% l9 C3 [9 A- R
    点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
    , H& }+ S8 S+ c% |& ~
      u$ ^$ Q* u  W* m! E- G下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    # q$ ?- d$ M% j% ^/ K- f& z! \$ ~# P: `
    TDM-GCC(gcc/g++)
    + L7 {3 ]5 @4 }6 n; q% cFor Matlab 2015; e0 ?% w0 i9 F1 i# `5 t' q
    Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。  |' A; B  Q; p" I. E& [
    1 K5 Z9 d2 e8 Z$ j# i+ d; [
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:. N$ G, C' `, C# }& h: w2 f0 ]

      K0 ~4 I5 v! f" W- h
    • 然后,还需注意的是安装路径不能有空格;
      / h! n2 d- s6 l4 A

    - p$ W: h) x5 l% L1 w
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:
        K) n' g: O+ r: A! \% ]. i7 F
    " i3 K) D1 O  o+ N( \
    至此完成!$ r2 f" j3 {( P- G1 r! n0 u

    * }5 x$ n4 i- i: l4 V
    2 I+ x( n1 J$ I6 `" T: cFor Matlab 2014
      z& q2 u+ E% }" k! L# ]1 X如下文章针对于MATLAB 2014a。9 ?7 a, R( A2 |4 r

    ' [( y+ y- U' |$ P2 n4 }+ O  x) @: j点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。! N  C2 |+ k1 D$ _, S5 |

    ; H' B0 i5 h. ?; ~' S7 y1 ?根据以前使用经验,安装路径最好不要有空格中文。& w' v3 t# O4 r
    ( z0 @2 d- P4 H
    安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    / J* I2 f) M) }1 i # x& i; g( R, M3 m1 E' I/ D

    7 n) E' p$ y: k6 B. x最后的战斗:
    7 g( N9 p, V* B1 i+ w因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:& `8 _% w$ ~$ x( F" L2 r
    8 M) Z7 D( W) X
    下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。% R  c9 y+ H) g& ^* {; ^( q

    % }5 ?6 V6 W! q* K9 c2 B, F在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
    ( [8 @9 T3 I1 b  \6 a- ~
    " j' ]4 A; ], S7 a4 [. Y9 K%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    " G% i6 B" z5 Q$ |' y8 f
    ( a: K. ?3 U. v9 y* o下面是代码:
    ; h  K/ u1 l4 o/ j: |$ o% n4 S6 S$ g
    @Echo off$ q$ d4 r9 M# E4 |% N" E6 g6 t! V% x

    - t6 @& s1 E2 j:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
    5 V& D( a0 E8 N::       parses it and only understands a very reduced set of commands:, C2 F" `7 ]! V  _
    ::       "set" and "rem" apparently, everything else is ignored (behaves as" l% i8 A3 k1 S
    ::       "rem"), so don't do any fancy batch stuff in here. There are some! g; |4 n7 v8 p% K
    ::       undocumented special vars you can set here that will trigger MEX/ M+ u2 S% ~" o  U: o0 R
    ::       to do fancy stuff.1 M. y; K/ {2 Y2 u
    1 N% ~4 _6 |3 h7 l: Z& r
    :: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
    % P# B. ^- o: e2 a. v7 G9 b: r:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
    1 z1 F5 R# F  M
    7 W0 m2 [+ o' Y0 b2 b2 ~6 J) Q# u:: Tested with the following:
    + n3 K) v6 e% h& B6 q. f; g, `% 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
    0 ?3 P2 P" B! F. a, }
      ]5 @9 F( X: k4 k; M8 Q0 }:: Set this to your Mingw64 top folder, where you extracted the above
    0 S  i  }3 T" J# Vset MINGWPATH=p:\mingw64
    / L7 l+ C, h. X* c& ~) @$ ~$ W' C+ {: m+ w5 l
    :: Leave these alone unless you know what you're doing.
    1 W/ B* d. `# v# V; d- Hset PATH=%MINGWPATH%\bin;%PATH%+ `/ v5 i: q( M
    set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs3 `) h1 R4 f+ i( T) D
    0 l# E$ Q% W) K! z7 H3 i( b
    :: You can have MEX run some commands before calling the linker.* {6 x/ b  A: ?
    :: The two examples below will cause gcc to output the full path to some
    3 ~8 R0 p4 ~9 K; y; K# i:: static libraries so you can link statically to them (see the
    * X! e, F# m( T! I+ e3 W4 A2 _:: LINGFLAGSPOST special var below). You can set any command here, however.; f" A3 T1 I) k. P9 G, h* g
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
    # ]' B  R: `5 b1 h, mrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs5 d/ V# E& x* i- }2 q) d$ W, y
    rem set PRELINK_CMDS3=...
      J4 w; `4 {2 }7 R; _- ]
    3 M& G/ _, E$ b:: You can have MEX run some commands also after calling the linker4 s; k( r, @! J0 M8 ]
    :: (e.g. upx compress the output .mex)) R1 y6 _, ]' a- U8 M0 r" ?
    rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    0 ^) O+ E# g/ a) |+ Erem set POSTLINK_CMDS2=...
    3 D9 }; K+ ^' f" k/ |, u5 j
    % e6 K2 K5 u6 K: ^  g* {) Q" J:: You can change these if you really need to.
    # i3 T+ `) `6 C% p' `8 uset COMPILER=g++
    7 f* N7 h; W9 l" r: ~6 z5 ^6 a  kset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE9 T1 N4 S3 u& t$ l3 t5 Z* X
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG: W* u: F1 z0 a
    set DEBUGFLAGS=-g/ |1 A  v6 W+ M. X- ^2 L
    set NAME_OBJECT=-o4 L- [7 A# v% N$ T
    9 P/ ?0 j% [( \6 c" N+ m- |5 H
    set LINKER=g++& _; f3 i- C" d/ Z* i& S" D: O% u7 t
    set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas. I+ y( O& w9 X: R3 ]% E3 Q8 T: a

    1 @, r  A1 Q2 w  zset LINKFLAGSPOST=@%TEMP%\mexstaticlibs- a( l7 g! N8 z, i- y& U
    set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"8 D% y4 B* y4 r' }; s5 h3 J- L5 ]! V

    ( ^$ j( F5 a3 }3 u# j5 A
    * c, t9 ~( g% N- e) y! f:: EXAMPLES
    $ ]( C5 m% N" z' J1 `:: ========# ~5 z# m* z$ I1 E

    ( W0 Z# r* o- X" m! d- B:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use4 \. ]1 e1 j9 H5 i) @3 C
    :: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
      U1 Y& ]* F+ H, F, @0 H3 e2 x8 J9 O& s( o0 l: V/ z9 v* J
    :: To add include dirs, lib dirs, or compile/link flags, do:7 c. o3 P- F  r* q! M4 E( }* G
    :: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp( t, m- ]- ~( \, N0 s. z- j( I
    ( ]: e7 k$ U6 m/ V  m6 r* W
    7 Y; R$ v& i0 M9 a
    选择编译器
    ' y& C4 {8 N- Q& }, \. @9 K. b! W查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
      l2 k3 r8 v2 |( B5 L3 c; ?. \
    : O+ o4 d; B. m. |- G7 i选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    + E; c3 w8 R; c) D, l ( U6 j  i4 P# O! C' w
    如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 0 A) U+ ^6 F# [- z$ W+ w3 a- B( M8 V
    $ @0 n# ^/ `3 `' d+ P

    $ j; _1 h$ z, T/ h刚开始我也以为不能用,后来试着编译了一下,竟然可以! / R9 [: C% x5 x3 X& M1 |8 ~0 E
      Z% D( I6 m/ B9 ?
    4 W9 E# w- u. M1 H. e
    DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!3 z5 P7 I, b7 a$ E& Z+ ~- I
      p+ _) |$ e: R! _6 y
    + h0 M8 e6 T" r, k
    编写c/cpp文件# d% }' P3 a  _$ H3 c+ g! l) X

    ) X* {2 Q2 T8 }& t  ]3 w与普通的C文件的编写有两点不同:% o; T( |+ |4 M* {

    6 z* N! B6 f! t/ a( a
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。
      1 p0 {' L- D7 a/ D$ x

    ! ?9 n+ n, z# W. I: Q下面以一个求和的例子说明:
    + c( F: i( U" S* Q3 z1 |: @" ?: l8 z4 V* S7 o6 p( W' j4 q
    #include "mex.h" // 使用MEX文件必须包含的头文件
    ! k! g+ B$ S' Z4 l! S2 F( G// 执行具体工作的C函数- X; ^# I9 B, J4 r$ a
    double add(double x, double y)8 ~9 }+ r% {" i9 n0 I
    {
    ( X' D& {# M/ m    return x + y;
    - L/ A6 x9 O0 y+ S}
    - X( H+ {0 V: ?- O, h5 Z// MEX文件接口函数3 f. P6 m1 ~7 G4 I6 S) L
    void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])$ G- w* ?- y' q% o. ~9 y5 u
    {
    , i$ n& k0 }- s% q6 c/ [) f    double *z;
    0 s& s/ i$ ?7 W3 o: w/ e    double x, y;6 s* p5 |1 a/ y
        plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);: D8 U, d" h- X! w: P# S$ a
        z = mxGetPr(plhs[0]);( v/ {, u0 o# k1 d6 @
        x = *(mxGetPr(prhs[0]));8 I" x. S4 N  |: m
        y = *(mxGetPr(prhs[1]));
    * L0 d2 a6 e& Z! `, s3 J3 w4 _    *z = add(x, y);
    . z; W+ ^8 n% F3 a2 r}( n8 Y4 C( B5 p8 Y% q

    0 \3 `6 r& }% {( ]
    2 W) u2 u8 N$ RMatlab命令窗口输入mex add.cpp,运行结果如下图: 3 g" w+ d# W' M2 w! |/ Y/ M

    " w! u* s! I! ~  z9 u/ E& l# @# N8 w- P4 h
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
    ; A) e: o" {% L. M; ~0 C
    . U7 H+ q( _7 q' c/ d5 lmexFunction函数介绍
    $ [# u! g* G( h6 d' H+ KmexFunction函数接口如下:' s6 V' c! V* g
    1 G% n0 y  X5 m( K
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])' B4 ?  u; J/ Z% l; o! k

    - G/ i4 |* _& g可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:0 s# x$ ?6 ?/ C$ }2 t: D

    ( ^4 M& S+ H6 f9 o( L参数        意义        英文全称        类型
    6 M8 m8 {, Q* t& p* Ynlhs        左边输出参数的数目        number of left-hand side        整型(int)6 h9 O) B6 q2 U  q2 W; k
    plhs        指向输出参数的指针        pointer of left-hand side        指针数组9 u8 @8 _1 [/ p" h
    nrhs        右边输入参数的数目        number of right-hand side        整型(int)0 s1 L3 ]+ m+ _/ z
    prhs        指向输入参数的指针        pointer of right-hand side        指针数组
    . h! {9 M, S9 n* u详情参考:5 ~, P; x* A7 d, P2 j8 ?" Q5 G

    " [0 |# E: w/ VMatlab参考-MEX库- N+ l2 @. B0 I+ O0 i
    + w7 Z7 Z$ f: Y- g: g" J( L
    MATLAB中mexFunction函数的接口规范(转载)
    # V4 y6 H; B2 w' O+ `
    7 ?: ?7 ?2 l4 |% e. W) pMatlab与C语言程序的应用编程接口
    . J, b3 l5 Z2 J7 Q
    : I; C5 t9 |; g  Z6 _8 Xmatlab和C/C++混合编程–Mex
    : z7 ~/ L4 s4 y# {2 ?6 d# {% l: C6 [* p+ k
    编译多个c/cpp文件
    , Y) R/ Q0 G! o* Q: v7 }假设A.c调用B.c,B.c调用C.c * }, q, L/ h; V0 z
    可以使用如下命令编译:8 q% I$ s& p& h3 o# L: B

    - Y4 G4 y3 ^# X3 r/ Hmex C.c
    . U& h: C; O* X5 u# Y! zmex B.c
    ( [3 _8 F& D- Z2 r* P; c, c* Zmex A.c! v& m1 M: d4 q+ f) J/ i3 V2 y
    , p9 w& m5 r* d7 z/ D
    % [. P/ @- D% o
    或者0 S. f: ]! v4 m: R4 u2 N* j  A

    2 q7 A+ u. }- V2 k! Kmex A.c B.c C.c. N$ J2 a, ]. n% ]' ~- v

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 13:16 , Processed in 0.187500 second(s), 27 queries , Gzip On.

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

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

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