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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    ( p/ x! A% B5 ]& x4 W! ?说明- K* B5 [- ^- `$ h, q) f- ?
    Matlab混合编程
    ' [2 Y- v: E; J2 k1 ]- s$ t9 }下载与安装编译器
    : T2 _' Y/ v2 T7 u1 N. GMicrosoft Windows SDK 71CC3 h/ R0 ~& a& Q9 m2 y5 P* {: f
    TDM-GCCgccg
    % y$ J/ N( K5 w9 j3 i; U/ [* G  h! BFor Matlab 2015
    " }0 w* T8 D) [9 @For Matlab 20144 ?/ v: v% Z: Q% H$ `
    选择编译器
    : Z$ _* e$ \2 }! [* K编写ccpp文件
    ) ^0 `5 y5 b  ?7 F" imexFunction函数介绍* T8 p7 q8 t+ d5 v2 U: Z
    编译多个ccpp文件) Y' m( ~  \# }* h, X" G
    一些实例
    % R6 u& @7 i7 y$ pMATLAB2015编译MeanShift
    2 D8 _5 X; A0 U/ [! R& Y5 tProblemSolution
    " p: ]7 J3 m! ]  G& t  }6 L9 f找不到编译器或SDK
    ' V3 d2 ^! L3 Q$ g3 D" sProblem. ]* p* O9 K' ?) ?9 [+ V8 ~& l
    Solution
    6 D+ K" ]( h1 j注意1 Y" w. K7 K0 X1 e% a) @& m
    error C2143 syntax error
    5 r  u* ~$ P3 {! DProblem
    ( v- y/ Z/ ]8 QSolution) s+ S) ~3 ^6 h+ [
    一些有用的总结
    + N4 H) q" k& q6 ]注意系统平台和文件路径" h9 D3 B2 K( j: D6 P
    运行效率对比1 C0 O, X9 Q' E- h( B' n  r* k* V7 x* {
    说明! ^7 i# @: N1 E
    记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。, k; F* K& [- r; b, y' E
    3 s! G$ j! q/ p7 J& P, H: A
    • 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)3 Z+ j) H9 X. X1 A/ W$ B
    . W. v) _- ]. c2 H6 C! ~

    / s, D0 a, k: i0 NMatlab混合编程
    ; M" C2 \; p& `下载与安装编译器
      ^4 Q' z1 z, q5 TMicrosoft Windows SDK 7.1(C/C++)) t2 c  v% m: _1 y
    点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
    3 X2 w: J2 }2 ]: {  I. x4 v  |! E" t- ]
    下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    0 M. f' A  l' o; `4 @& Q. b0 ~$ N" u9 Z: I  x7 g( z* ]
    TDM-GCC(gcc/g++)# t* U3 t( j. J3 q2 ?/ {: I: _$ L
    For Matlab 20151 Y1 J# h# p9 n- u& Z- e9 ^
    Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
    % l. g4 [& K. G% R8 e0 n# k' l6 |5 R! z5 v+ Z. ^- [* |& ?. h
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
      2 G9 |6 _) p" s% _1 [+ d; }9 l- U$ [
    ! Y& R) `5 Y$ j* t' a- O& g- b
    • 然后,还需注意的是安装路径不能有空格;
      2 h  B( @6 ?. m  o( G3 d+ ~  G, y& ?

    2 p+ U% h7 L9 S; q+ G  P
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:  M" U+ N" W  `- J8 X5 q" h2 I6 l

    0 u* Y& n5 G6 f3 u" w  q至此完成!
    " f% O  c+ ~7 d+ J9 W$ ]! a" l$ U4 W; M0 \& m, l9 f

    $ b6 r. e4 G1 R2 tFor Matlab 20145 w/ ^8 K) t( w5 ?
    如下文章针对于MATLAB 2014a。+ N9 y' h- b7 {) G: e$ A. x

    5 M3 X2 C& Q* U6 T% p8 l& b; H0 I) V点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。5 B9 o% k' L4 N+ V" @: d7 e- m
    ( R* \% D! l9 o+ U5 ]
    根据以前使用经验,安装路径最好不要有空格中文。/ ]+ W, E6 b4 [9 A: H2 \6 U" x# j" o

    * F& p6 l5 q7 D" ~) _; M安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    & }7 F; }' c' \% B# J8 O( k9 O
    ( D! ]- E* y: m' v) c9 D' d- K- w7 u2 b
    最后的战斗: , w' v( M9 g4 ]5 z3 |
    因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:& z4 M& j) H) _) y) @

    - ~8 k' C' I- ]9 U- m$ k! U3 B下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
    6 T* y4 r) Y' J8 }' x& E
    8 E  I& j% P+ C' L  W+ W在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
    1 s! N, X  d' I- I) B: @# u; k) t. r0 `; i: }
    %USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    1 ?6 M" K) r# l% B' b. T, P/ F
    下面是代码:, b8 W* b8 `! ^( R

    + y1 G+ J9 A- N# @+ A@Echo off
    0 ^; t2 q2 o! z  Q. N! {; X. {- p  E9 w
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX5 c" f+ D2 t9 o
    ::       parses it and only understands a very reduced set of commands:
    : E( \7 {0 s, Q: G::       "set" and "rem" apparently, everything else is ignored (behaves as1 O: ?) P; ]% ~6 L
    ::       "rem"), so don't do any fancy batch stuff in here. There are some( f$ X/ [) R+ i3 s; o0 x) p
    ::       undocumented special vars you can set here that will trigger MEX
    7 F: W5 Y6 Y2 [# b: W::       to do fancy stuff., V1 Z, F( r7 k. _

    1 t, m/ _7 g+ x' Q# O" W0 @. w) t:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:! v5 o; n6 t0 ~  H: y! ^; `! ]
    :: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
    - _3 v( K0 j- l! z' U/ e+ K  `/ o% h7 j6 U" ?) z; a' t
    :: Tested with the following:
    , r5 T% q/ a( C: T8 t:: 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
    ' V% d* y2 A# [) F, s2 V5 s, n$ X; t7 {7 P# K
    :: Set this to your Mingw64 top folder, where you extracted the above0 q: q  T/ Y" r, }! l7 t
    set MINGWPATH=p:\mingw64
    8 _! c  b3 @1 `  r7 ?4 U2 R& W6 \. D) T9 Q8 N9 N0 N' T5 z! e# \6 L
    :: Leave these alone unless you know what you're doing.( d9 E; N' }  u  G3 O
    set PATH=%MINGWPATH%\bin;%PATH%
    ! O6 N1 p4 V; c( F; O5 X$ ^/ I* ]set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs7 e1 x' B6 ?, p: ?7 f
    ; z; L2 v2 d* P& w$ {+ \
    :: You can have MEX run some commands before calling the linker.4 A' U/ U2 k" B& r) }4 s( a
    :: The two examples below will cause gcc to output the full path to some
    2 o: _0 R: v& w6 L( n" d:: static libraries so you can link statically to them (see the
    6 F/ f# ^. W* M( g5 t( t:: LINGFLAGSPOST special var below). You can set any command here, however.4 i: V1 h1 P+ y* `- O
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
    + k- S& h6 q1 _% v- Xrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs- E: h3 I4 |! Y  g8 A
    rem set PRELINK_CMDS3=...
    7 o( \+ V3 V; B9 D  D0 A
    + u1 F; T, C0 u. J9 R:: You can have MEX run some commands also after calling the linker- |9 u9 m0 W% C* [1 |9 U: `
    :: (e.g. upx compress the output .mex). z% X# i6 k6 ^1 q- b: c
    rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    8 ^0 N: F- Z# G( N+ t6 Jrem set POSTLINK_CMDS2=...
    : I1 {7 ?8 r% d, W* K4 P: K$ z  i5 s3 R
    :: You can change these if you really need to.
    7 B7 D! o. {$ aset COMPILER=g++0 e) U. h. z1 x; p3 E: r$ C
    set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
    ! h8 `" ?5 [: z- Y, I% pset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
    + v3 x% f, n6 F8 j/ M" P) Sset DEBUGFLAGS=-g
    % ]% \0 t7 r% d/ c. f% nset NAME_OBJECT=-o/ R$ Z9 v" \0 x: ?8 Z* \# M% Z: W
    * q% d4 |' w8 q% ]5 t
    set LINKER=g++
    0 f& ?  R: l9 R& U; [' k$ Pset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas- }% i5 z/ O2 E& B& \( _
    6 N/ P! S- v6 o6 i7 W
    set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    ! X$ r% G5 O- ]set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    6 G+ J  s9 g/ w/ s4 i$ F: L5 |' b$ M

    ! B, T" u( D; c" g:: EXAMPLES6 I0 Y: ]0 b4 h0 X1 S: G) Z
    :: ========- {0 G% J( y6 d5 m

    ) B& u9 [, J3 R' C1 A3 P, e, f% d" x:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
    . P! Y- T, E. w) d* o- h4 D5 W:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.3 z, @$ |/ |2 W
    . r1 Z, g- A- J9 a5 z8 n
    :: To add include dirs, lib dirs, or compile/link flags, do:1 i. r; h0 h1 B
    :: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp# X, p1 U9 f+ Y
    ) [* M; K9 w- }, E9 Z- D  s5 Z$ x
    $ ?& ]8 k; h4 ]% s2 \& ~2 ~% m( D
    选择编译器
    * G7 r( ~6 B# L2 `查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    , R8 t- E/ ^& |# N/ ?1 Q  P  t
    & L- i- V' ?  g$ @- ~选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    9 w% {1 E1 d. v* h3 J
    2 g% `, @2 I4 t0 F如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
    ; M/ t% M0 u& X 4 g& k) r7 f3 ]+ X8 A7 E' g+ L" E

    9 u. V7 J9 ^' O" A+ w4 W4 o0 @: j刚开始我也以为不能用,后来试着编译了一下,竟然可以!
    - d/ V' ?$ x+ s: L" f
    , B$ n. v9 U- H5 Z% R% d( {( j/ _, ]- s9 N( R
    DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!  @# N: w6 g+ Q3 p

    , h" T3 i  T) U! V$ b, h" I  R9 ?* T5 g1 Z
    编写c/cpp文件7 D. @9 z6 R+ @* X% q
    0 n/ _  H' `( E
    与普通的C文件的编写有两点不同:
    1 g& l9 Q+ L. B& H0 ?# K8 q1 I/ V2 u" d& h2 u
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。  D( A% @( B* {" q
    $ I- H/ M8 d0 n9 w/ x* v& x( ?
    下面以一个求和的例子说明:7 x& m% b( @3 V. b( A: I6 s
    9 O/ x; p) I+ R. a' _) t
    #include "mex.h" // 使用MEX文件必须包含的头文件7 ?9 H. A, V* I
    // 执行具体工作的C函数
    / g4 v. r  e, N5 i4 Gdouble add(double x, double y)
    9 X& J$ `' D1 a# Z# E4 W# q{) q+ Y5 ]2 ]/ M
        return x + y;( Y1 f  k' j  [% D& G/ J
    }# O. n" f( ~$ K. x
    // MEX文件接口函数
    ) t. _* q- a  }4 O; Kvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])4 [3 D8 d; s7 l( u0 d% Q7 {
    {2 s3 N& }7 S! W8 Z3 e6 c; k  r
        double *z;
    / L1 U0 @: [- U2 j; ~    double x, y;
    ; t' j# r0 p# K8 \3 A) c' |# s8 ]    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);% |0 M% z6 j9 `. ]! M, i) v
        z = mxGetPr(plhs[0]);! I0 Q! m0 X$ H3 B
        x = *(mxGetPr(prhs[0]));7 T  _% x6 R$ i2 H. w9 d3 l" W$ L1 o
        y = *(mxGetPr(prhs[1]));
    ) r. y! E) E: I) A4 F( k0 g4 e    *z = add(x, y);
      I2 H8 j; `8 Y9 n}5 [; s( [" y' S" D& K9 u- P: H

    $ n7 M/ D" X8 |% k; F- V8 q. c; ^, J# M; V
    Matlab命令窗口输入mex add.cpp,运行结果如下图:
    / L6 p# b% @; i  \- n3 ?
    5 S$ l2 c2 b' a5 W9 ^% _3 o3 y9 L( y; l' o/ A1 b
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。( P' ]2 w) a9 P( ~

    # n& h( F9 I" t7 e; {mexFunction函数介绍
    - i9 U( Z$ K/ @# a& _mexFunction函数接口如下:- g# l5 ?; C: a
    ! o( _$ b7 J- {
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    9 \6 }: f, d7 W2 K- j) G7 A/ {2 r; O' H7 ?8 [( u5 E
    可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
    ) |: O5 M3 L3 k+ q" D3 n# ]) g5 e" x) x
    参数        意义        英文全称        类型
    - i( A' _* {1 W1 f* I5 R! Lnlhs        左边输出参数的数目        number of left-hand side        整型(int)( L' b. b& j2 J% k1 q* \- e
    plhs        指向输出参数的指针        pointer of left-hand side        指针数组
    ( _) q3 j! Y5 n, Xnrhs        右边输入参数的数目        number of right-hand side        整型(int)( k; _( m8 l' k
    prhs        指向输入参数的指针        pointer of right-hand side        指针数组
    5 Y6 f7 u) ^  j; T详情参考:
    , H) v; X% y# D. a3 O
    3 d9 f4 i4 ^5 fMatlab参考-MEX库
    3 ^" J3 t- O  B) g# A  T
    " R" W4 r: p! f) h( H3 A/ }& YMATLAB中mexFunction函数的接口规范(转载)
    * L+ p  ^8 R& M8 W5 p# S
    . _% K8 v9 B! }% R! H( TMatlab与C语言程序的应用编程接口
    * e/ f. `$ e* `0 y& V
    ' W: s3 L. D, l% Bmatlab和C/C++混合编程–Mex
    $ u. z, Y; D6 W$ c) g! K* M5 o3 n: Y
    编译多个c/cpp文件
    7 U# @, @0 ^0 r: H5 E假设A.c调用B.c,B.c调用C.c
    / ]  D: b2 }* M- k. L; ?可以使用如下命令编译:0 |2 l$ A: ?0 E7 [# H

    & Q* m9 Q; q: a% z1 E0 f" rmex C.c
    1 K8 S/ u2 ^! @: M( }  amex B.c* Q9 @$ W2 e/ y
    mex A.c6 O6 j. U6 I! T* Z

    ' g& [" y% X" N
    2 \/ L. Q: H0 Y, M6 n/ S! \或者
    $ h1 p' Y' G$ J! \' Y  I: }8 p
    4 V, D6 ]# k5 I7 @4 m& zmex A.c B.c C.c3 r" b  }! b" k9 Y7 ~9 k( H

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 01:31 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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