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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x

    1 E0 _& L* o. X) ^# ]2 O1 O7 Z说明
    4 K0 p1 n* c  \$ B$ K& w# }Matlab混合编程
    2 U+ H$ R" }8 ^& ^下载与安装编译器4 }$ ]; M; F  r4 T$ U, ^9 L( V6 K
    Microsoft Windows SDK 71CC
    # U/ K2 U# B" \3 S& I: f! jTDM-GCCgccg
    & s4 W( B% `1 l1 dFor Matlab 2015* N3 [" t: Z, m( p6 e
    For Matlab 20146 t& a* O) d) |. S* V! h8 w/ [
    选择编译器/ e! B0 C" n, ]4 q* \1 A1 ]
    编写ccpp文件
    5 b" b5 w0 [# u) \! h# x- BmexFunction函数介绍: {  s! t7 q+ s: {8 D) B/ a: o
    编译多个ccpp文件, m* x" v5 J- b# y
    一些实例
      }( {$ o) i, |7 E" }MATLAB2015编译MeanShift; k9 Z2 L+ L$ Q3 F* l1 Y
    ProblemSolution
    ; X' S6 e" L( L; n. g找不到编译器或SDK6 N6 g$ _/ u1 `1 |$ s) s. Z
    Problem
    6 ]' M$ U7 ^( y. y6 K6 a2 KSolution' u* j. e: H& ]9 W" G
    注意
    4 C9 Q4 `+ i7 i3 `; @- Eerror C2143 syntax error/ [' s  b2 A1 i! P9 V' U2 O
    Problem" \9 S, [( G$ h+ }( _
    Solution$ _' b; F+ i  I1 W& r
    一些有用的总结
    7 |. {4 N8 X: F4 X1 R+ r9 Y: m注意系统平台和文件路径
    6 R" N: h! r3 \( }运行效率对比
    ! d9 y$ r! q, y! x( D3 G说明
    ; j' ~1 j- C' _. t记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。1 U4 T. S/ T9 a

    $ e: h* `: w! S3 C% O0 F
    • 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)5 f% @1 ?' Q- c  a; b1 `7 N
    & r. ^4 j+ L) i/ ^
    ( @0 ?. B. y* N+ t! B  A
    Matlab混合编程
    - R; [9 }0 b4 C; T下载与安装编译器8 `% p( O- H1 y7 m. g" u
    Microsoft Windows SDK 7.1(C/C++)+ f1 m* n, ~1 H
    点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。' \9 Q# f6 v& A6 c
    6 d  Y! Q- ~2 [, h: N4 ]. t
    下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。. M/ N7 V5 N1 k% ?4 Y' Q% Y" |* Q

    0 V# U6 d  l6 R0 V/ STDM-GCC(gcc/g++)
    + Z' y1 \; M8 a$ T5 o7 XFor Matlab 2015! |9 Y+ t0 |5 P  p
    Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。) f+ c" B) y/ d# [, b$ v5 Q
      }8 H7 n* _, Z0 H. _; r0 P
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:+ Y1 m; J1 S7 Q7 D, e
    7 `- D4 S- W! s
    • 然后,还需注意的是安装路径不能有空格;
      2 `* ~$ ]; P* S. E2 C7 e8 ]

    3 y' [- u( f2 H: c6 b0 c( c1 g* V
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:1 B# A' |2 c) K3 {3 }& D) q

    9 [4 ^: d  `) s8 A至此完成!0 _, U# ?( |6 t0 a, q/ n

    9 H; W8 b+ u3 \, g; o  P* ^5 ]; s- ?, r) s- A9 J
    For Matlab 2014
    3 M0 W: M1 C1 T) {4 j1 w6 S, C如下文章针对于MATLAB 2014a。. s+ y* I+ i, s7 |, U" u, h& c

      w& T- j8 s4 o( T) {2 H( y6 R+ M点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。6 X, `5 Q0 S( @" _0 W6 g) q* F) W! z/ ~! I

    2 ^0 t1 @- v' m根据以前使用经验,安装路径最好不要有空格中文。
    & P% n6 y6 E) Q7 V6 i6 t% r! L, c% G2 H- T3 D3 c/ A2 @# j
    安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    + f+ K& C7 ?! Z- E
    2 @: J+ w1 Z) u8 @# m, d+ O$ H+ I' P
    最后的战斗: ( B9 U/ E3 _  ?# e) O8 ?+ i
    因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:
    0 S2 _8 L7 L# N  H% c$ [- y3 o0 m+ N5 f
    + T7 Y& t0 J$ L5 m3 O- J* Q3 |下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
    , x: B4 A* a; Q/ b2 `8 Y6 B+ W/ X1 m; Q( b* w& X9 N0 o& E1 `
    在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):9 F" z( k/ w# i6 l: P
    - X7 ?/ W4 k# R' |; V2 T5 v
    %USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\$ M5 L. p  z* M8 A

    # N0 t( @" u8 h4 H# G: }下面是代码:
    4 k2 ^( |& `+ _$ C+ K# a5 x; F0 R; |5 H/ A& S$ W
    @Echo off0 I1 ]6 V) w$ Y: D( Q
    : U4 m0 a9 E9 a9 c
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX& X* x' A3 ^) B( E2 }: s" a
    ::       parses it and only understands a very reduced set of commands:* {8 [6 ]7 j: C' g- ]" X' d2 B, c) V2 P
    ::       "set" and "rem" apparently, everything else is ignored (behaves as( f0 `4 u" a2 f8 ]
    ::       "rem"), so don't do any fancy batch stuff in here. There are some% ]! @* f3 x; r! r
    ::       undocumented special vars you can set here that will trigger MEX
    9 P% d+ [& x0 ?3 ?/ z( Q( g::       to do fancy stuff.
    ' g3 s( i# Z: Y$ }" T
    # q5 k+ I* C+ I' c5 V:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
    ) c# ^& z8 I2 l:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/1 q  f4 N6 m! J" ^: s! X$ }' i" l9 _
    6 x. Z1 q# r9 h3 ^/ P( W- w
    :: Tested with the following:8 N( t( j8 k, Z& J
    :: 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" p( O+ }$ b

    / y8 Q( a' d& G( W' {:: Set this to your Mingw64 top folder, where you extracted the above" y( r% e$ ^+ U# R
    set MINGWPATH=p:\mingw64
    : q* U5 ~- E- a4 b
    ; L+ P: R( V5 T& }:: Leave these alone unless you know what you're doing.) I  k8 g2 m! K3 o3 m" m+ q
    set PATH=%MINGWPATH%\bin;%PATH%
    * G2 B/ ^) M- }4 G; {set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
    * I4 l- X& |* V8 k. l- z* \# f' ?6 a4 b1 D
    :: You can have MEX run some commands before calling the linker.+ J, B* ~: X! J# `# L5 o
    :: The two examples below will cause gcc to output the full path to some
    $ h+ W9 r% ?2 U) I' c* Q" A:: static libraries so you can link statically to them (see the
    / G/ {2 r. A* o9 t:: LINGFLAGSPOST special var below). You can set any command here, however.6 e2 q. Y% H4 ~( z$ z
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs- T" M$ Z* J/ `* I4 I) x
    rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
    - T, w1 m1 ]* Jrem set PRELINK_CMDS3=...! I7 e7 g  l/ _4 Z+ H. F8 Z% x
    1 K7 t0 d0 Z! l5 y+ E
    :: You can have MEX run some commands also after calling the linker" _% G0 ^8 Q# _6 R! o
    :: (e.g. upx compress the output .mex)
    2 H, V, Y- J+ u$ {" G1 Wrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"6 O& j( e: ?  c6 c
    rem set POSTLINK_CMDS2=...( h$ g3 A3 }! i) J8 z- x- [

    7 C# C% t2 ^8 ]& ], j:: You can change these if you really need to.- m' j, d7 k8 u
    set COMPILER=g++
    ; c* q+ l0 ^$ [- [, mset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE7 o! a) r0 u% ]( R& M0 m. G
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
    ( u9 k9 U- {0 A# k5 r8 I* a9 Dset DEBUGFLAGS=-g
    3 }+ w- u+ v1 Lset NAME_OBJECT=-o
    6 K7 i9 t: a& d2 P+ o+ L, v# f
    " @5 C1 C; }/ g1 w' cset LINKER=g++
    / Z6 u7 H- U* x. L+ G- _& uset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
    6 a6 w! v, `, g. G
    6 T& e, _" b% E& Q. e% G6 |set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    % H0 t0 q0 }9 S  p% Fset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    , g0 R+ d, B+ d' F) q
    , t& Q+ {7 R# P- Y& a! g9 H
    ; [2 K" T% r6 \* \2 l; y  J:: EXAMPLES
    3 t* F$ b" y7 ]3 {7 T+ V:: ========' L% i( @4 i" ]" ~

    # w. S5 s- j2 H# u1 q) k2 _:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use5 a& S' O" `' y3 J
    :: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
    - E- j  k5 r5 H" L5 Z% \" R4 t& x, N8 T4 W+ d, A* l, `8 {
    :: To add include dirs, lib dirs, or compile/link flags, do:
    5 a$ J9 G  m; c. H8 }" G:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
    ) Q" A" o+ U, p+ G  Z7 m
    ; l; o/ ~9 g0 c; m- f0 Q5 `/ B* u) d* x" H& F
    选择编译器
      c  A0 T5 Q5 m4 H查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: 9 d) |$ |1 O2 {6 b  b5 \7 C- e
    " e- v  p; Q- _+ p) q+ m
    选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    % F4 h; A. q+ a! e* R$ C
    ; C: I7 o- T( M3 \7 ]7 B如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: , U( T9 {9 f/ J
    0 ^2 g, ^0 R5 b" c

      r4 I% ]  _2 z/ {8 Z' m1 O刚开始我也以为不能用,后来试着编译了一下,竟然可以!
    2 K( r+ W/ g+ q9 H' V$ f
    7 y: g* U8 g5 o9 ]
    7 n+ \& }. e4 B# ~DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!* o+ b9 n1 p; g1 [, p$ S4 q! U
    9 Y" p5 K; o6 \0 H* \
    / v& y% F7 N0 s
    编写c/cpp文件
    ( b; \# B: J- k
    # K' ~) T) ]7 x- a- j  E) _与普通的C文件的编写有两点不同:, {% U; \+ A$ W7 c. |

    ) y, e+ Y# g3 `3 S8 I! J
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。9 G: T3 y3 S- r+ R1 ]6 Y% ]- ~

    3 _7 I; ]1 O: g+ k7 _4 a下面以一个求和的例子说明:
    ' a3 K4 [% D2 [! c
    9 H! ~* O+ I1 A& e! \3 R  s  ?#include "mex.h" // 使用MEX文件必须包含的头文件
    4 q/ U* w/ ^8 A; x9 v# `" `$ q// 执行具体工作的C函数
    " d0 g: I/ j0 R$ Y4 B/ s# ?. v+ _4 Hdouble add(double x, double y)9 i% F) _* o+ k. j( i5 Q- \" T
    {% c$ o4 b; A1 ~; V5 K( ~2 a7 e
        return x + y;
    , i8 p9 i4 |! B$ t}
    : ?. U( ~% Y/ J/ q# Z/ {// MEX文件接口函数
    4 F  v6 s2 X( qvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])3 |; ^+ v, T& o% r. B3 t$ l# Y
    {, E! g; Z( f) O) _
        double *z;& L; e$ S% ]) }8 S# j8 l# x% [
        double x, y;# V2 s5 `. g+ R( _
        plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);' R, @6 @/ {, }
        z = mxGetPr(plhs[0]);9 }$ ?# Y5 r5 c/ f
        x = *(mxGetPr(prhs[0]));
    ) ^6 r* c. |- n% a3 V    y = *(mxGetPr(prhs[1]));
    * T2 t# r. I+ B+ M) f0 m. ]$ @9 r    *z = add(x, y);
    ; N8 \) s  ?# L& g* W( h# @! S' h}
    2 a1 `+ ~7 L& A8 I+ L- y9 U+ D
      E! F6 \  E7 r. a  O  r
    Matlab命令窗口输入mex add.cpp,运行结果如下图: * N" |$ x; i/ W: s

    8 X- [3 J$ ]) r( W9 B8 t  i* d5 ]5 h3 b* O! \! M3 @
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
    # E/ [5 i/ @+ k4 I% l9 k+ M; E' J9 S  N. E% ]2 l+ J" v
    mexFunction函数介绍
      i  Y  A5 E6 B( x4 ~$ @$ JmexFunction函数接口如下:/ s+ O" n3 f: r/ e7 {
    2 `! }1 Z4 j5 {/ V6 \0 ^
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    , C- e' d% I+ @1 W8 h0 a# l' P5 t8 @0 c5 t* Y
    可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:# M( v" e: ?% C' _0 w+ }
    / k% l7 U# j2 ~$ |
    参数        意义        英文全称        类型/ j4 V( W) }; m1 x* l" f
    nlhs        左边输出参数的数目        number of left-hand side        整型(int)6 f6 ^5 ?7 v0 I! C4 M1 @
    plhs        指向输出参数的指针        pointer of left-hand side        指针数组
    2 {  A, A2 p! O9 J" Inrhs        右边输入参数的数目        number of right-hand side        整型(int)
    2 z& ^3 X* |. vprhs        指向输入参数的指针        pointer of right-hand side        指针数组  M% f; Z/ G3 `9 b$ [
    详情参考:
    7 [, |$ x3 o1 S" W
    ) ]4 c7 Z) ?' x) W2 kMatlab参考-MEX库
    5 V( t8 y1 d" m
    7 a: z( e6 I: ]1 c% QMATLAB中mexFunction函数的接口规范(转载)
    ' W* a: N2 F) n8 S% F* o. R/ R8 o, x. ]: d2 |0 D3 Y* ?
    Matlab与C语言程序的应用编程接口$ N) ~1 g0 n( v* l

    . z# x( T1 Y' a: j* Y6 b. fmatlab和C/C++混合编程–Mex
    6 M& n' F  P) J$ D1 F
    : f* Z* O0 L8 F编译多个c/cpp文件
    1 J0 j4 C, e  t假设A.c调用B.c,B.c调用C.c ! K* q# r" p8 e' w7 w* }
    可以使用如下命令编译:+ H9 {) Y+ R9 v; n" v

    # p, b/ q0 K/ C7 [mex C.c8 \; w: H; \  d5 g1 @$ D
    mex B.c( R8 [1 j$ F! T0 g' q
    mex A.c
    7 S0 a1 m5 l; x) M* i7 N1 K) g' U) Q  s9 d% V$ [5 x

    2 W/ C# L3 @# W% x或者
    $ e  c' Y. t$ _( J3 M* f8 y# h
    # }0 ?6 s) N4 hmex A.c B.c C.c& t; f5 ]* a' m5 A# ]& c

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-10-6 13:15 , Processed in 0.140625 second(s), 26 queries , Gzip On.

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

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

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