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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    * Y) F% K0 S$ i0 V2 p
    说明
    ; f% K# g- W: \# h' }# j9 A- \$ cMatlab混合编程
    5 ~% \) [* q$ w5 w+ J下载与安装编译器% B4 v; E6 d" \# E
    Microsoft Windows SDK 71CC
    * c2 q5 `* O8 E  BTDM-GCCgccg
    8 W2 b- J; z2 r" n+ UFor Matlab 2015! ]* l3 [; J) y/ K
    For Matlab 2014" b: K) C6 s* C  B$ K
    选择编译器
    4 M$ {6 ]+ @, }( Q- u& l7 C( s编写ccpp文件
    8 X) J' D9 [$ ^; C2 umexFunction函数介绍
    3 X6 ]. G( A, ~. C4 v编译多个ccpp文件
    7 E' r6 j2 N4 i9 F一些实例
    & h4 z1 b. F2 nMATLAB2015编译MeanShift% H& B3 t- V$ ]! L: E  n5 g
    ProblemSolution2 I* p5 _5 b* I4 \
    找不到编译器或SDK2 V/ y& u; z6 H' p# W* y: u
    Problem( S' X4 ]+ p* q7 E5 r4 u: a+ d! v' Z
    Solution4 ^( n7 P& x6 m9 D" Z' S( G
    注意9 [4 d. T0 [% {: ~1 l' X( w
    error C2143 syntax error
    ; |" J# ?7 q6 R* {  K; L2 W* G# z# QProblem7 k: h% O8 ~8 U1 J+ n
    Solution, H" v7 l5 D5 H! t! R
    一些有用的总结
    , x, D# w0 |. ^% B8 R* F% o注意系统平台和文件路径
    4 I4 D5 W: \# B运行效率对比
    9 @* S( \# J0 a: g说明
    , R9 _8 f" b0 V* Z, D9 }记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
    * g, i$ Q+ ]+ i  c6 m2 E% T1 o( ]8 d. v* i  r1 t; C
    • 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)( E1 q' A8 W( @& m' H/ q, F
    * d+ H! ^1 G: o: @9 J3 {! m: Y
    9 ^4 @& k+ t  c: p  x
    Matlab混合编程+ d0 C6 C' ^1 j) h
    下载与安装编译器
    8 h% ]) c8 h/ g0 e! PMicrosoft Windows SDK 7.1(C/C++)
    ( j2 B: _+ w& ]3 U1 \点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。! y+ k7 i" O9 e8 m6 O

    * T# Z' N' U7 Z! x4 U; i4 i# P6 R下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    # E! {2 h- j" i0 F5 a
    : R$ ]1 B) U$ f& kTDM-GCC(gcc/g++)) o2 _6 @4 ^! p( ~& j, I
    For Matlab 2015
    , z2 g3 W1 `4 r4 k& fMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
    $ I* q: l, m9 n3 g  I' S! N( u8 }7 `, R9 q$ h
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
      8 t2 g; ]! k! `+ A. K9 d

    ! W/ w, R- o5 `8 ]
    • 然后,还需注意的是安装路径不能有空格;! {, M+ A: P5 W, C$ l9 T

    5 Z8 }. T2 \' N' b( O3 @
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:
      ( B  {/ h% z$ [$ i8 x; ^

    2 n- ]5 [: ^9 Q/ Q9 Y至此完成!
    % ^+ _& T8 a: {8 W1 s! _7 K6 \7 ~! j2 T# Z* v  v6 _
    & F6 F6 I3 F7 z5 {) A% C9 S/ }
    For Matlab 2014
    * U, m4 q! Z; r. u) ~8 A6 p- V如下文章针对于MATLAB 2014a。
    , B( C/ k. Z9 h5 W9 P1 M- r/ O/ f. m8 y
    点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。* |- |2 B* L4 r" J3 S' j

    - N5 ^% a( {% \# v根据以前使用经验,安装路径最好不要有空格中文。6 [3 H" W* P$ ~( F( `
    6 _4 I7 @3 K7 P- T4 B3 r
    安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    0 r: a2 l1 r( } ) v  |6 N6 E# Z" l1 s. H% a
    ! P* T2 g" V3 @3 q: H; y2 \9 f
    最后的战斗:
    - ~; Q; [. P( ]. W( k0 t因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:
    8 H, K5 o/ c9 \7 n8 Z8 \4 ]* C* H
    下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
    8 u! i2 t! ?& ?& E9 F- I3 q
    ; E9 d' Y" t$ B8 N. M在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
    ; C7 S% t9 e3 ~* f3 Y# c
    ( z; M3 W& x6 u5 G- b$ t9 L%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    4 f9 {, g, @& G, r1 q  N/ z8 R- ?- s2 K9 ?
    下面是代码:. v" u2 O2 t% j: l, P3 `
    3 T, U% _3 H  G% I' H
    @Echo off
    ; Z4 F5 ?! b5 P3 M7 _0 s
    ; r8 ]# C  \2 S: e:: NOTE: this is actually not a proper .bat file executed by Windows. MEX! l- |" ?7 H7 K% _
    ::       parses it and only understands a very reduced set of commands:
    & P! G' b. u. H::       "set" and "rem" apparently, everything else is ignored (behaves as
    7 W' B& }. S& D: e/ k$ W0 g* I. ]" T::       "rem"), so don't do any fancy batch stuff in here. There are some
    4 L3 n. }7 Z9 h" Z" z::       undocumented special vars you can set here that will trigger MEX
    * x" P% `( I: e. Q5 z::       to do fancy stuff.4 H) |, v  Z% {* k5 _

    - m2 w% l7 }0 R8 L% z6 X0 ~:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
    ; p3 A7 J+ l2 `+ p:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/' n& H1 b) _; U
    6 D! f% {, J/ T- W  ^, n8 ~8 X
    :: Tested with the following:
    / Y' {9 i: a5 b# v& |. P:: 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
    + y' z( s% M( |6 O" I/ e
    5 J$ G" r' Q& X8 g$ f% h1 w) f:: Set this to your Mingw64 top folder, where you extracted the above
    # X2 k& @3 A$ |5 q& N8 Q0 @set MINGWPATH=p:\mingw64( J: B% _8 f/ C
    ' i6 M+ v$ o, J$ u
    :: Leave these alone unless you know what you're doing.3 Z6 r$ y0 H' g  f# V  S4 \5 ?
    set PATH=%MINGWPATH%\bin;%PATH%
    3 i3 e* t9 Z  o/ ~! }2 Tset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
    / a- e3 l5 h8 \) k3 Y% h+ V* o% C' }  E9 ?; J
    :: You can have MEX run some commands before calling the linker.: D8 [6 i, @6 R! U9 f( ~
    :: The two examples below will cause gcc to output the full path to some$ @! U3 c6 ]0 K/ c# G3 b
    :: static libraries so you can link statically to them (see the& G' G8 i1 w" h$ Q7 H1 \1 M4 d- R
    :: LINGFLAGSPOST special var below). You can set any command here, however.3 r9 T2 z* r% C  `1 ~
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs4 A, X1 e  i" r3 ?
    rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
    + K- k2 P* V' K9 G: `  m& r- Zrem set PRELINK_CMDS3=...
    % k0 ]. k! I& x  J( o+ f& G
    5 i1 j5 r. }5 e:: You can have MEX run some commands also after calling the linker
    4 L: d0 ]& `4 U, C" L:: (e.g. upx compress the output .mex)
    ! j2 @2 d5 y3 U# C" i8 ?- erem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    ! i* L* ~' H, Z' o4 \* M( i$ frem set POSTLINK_CMDS2=...8 N1 K# Y9 D$ q  V& r

      y7 ~$ d2 F# W5 U:: You can change these if you really need to.
    ' ^( o- n* I( x! q: ^. Z/ d3 Xset COMPILER=g++
    & a4 r# D/ l2 H& t* j0 mset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE. H2 Q1 w: k5 N3 F. c
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG- N# c' \3 j7 _& a$ k0 S
    set DEBUGFLAGS=-g
    " F2 r. I- p8 _/ Z0 p) eset NAME_OBJECT=-o
    9 T  W% N1 j! y9 ^0 Y7 T, @' \: z: n8 d0 J' j
    set LINKER=g++
    , }! f" w- ]# G7 G, x" k* }4 Vset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
    ( I" ]" ^5 v5 q! `* H% C" U6 e, _; Y" @% ~$ G3 d; l  X
    set LINKFLAGSPOST=@%TEMP%\mexstaticlibs% x; B% g3 _- b; O, K' U
    set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"6 s3 x* u5 H! m' @7 V

    9 V% B9 W- B! i* d5 q6 S$ R8 F* a0 m6 V. ^# ]* A
    :: EXAMPLES6 Q2 F/ U8 U  u( E
    :: ========/ B, b7 T! c. _" I6 P. Y

    & K2 |3 s: O+ t) r" N6 }:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
    % Q# K8 D$ c0 i5 w- q& l:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
    7 _6 F6 t& ^* {) I
    8 N. p+ X' P# a0 d5 \4 b( r:: To add include dirs, lib dirs, or compile/link flags, do:
    ' g, i+ ]7 Z' K$ H& d:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
    : l2 ]0 R3 h3 d9 T; w5 u+ n4 k/ C/ g7 d0 |

    ; X% B% {7 e1 Z- t$ t选择编译器
    0 K& M1 U& c- v6 a, \9 W% N查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果: ' R$ |$ ~8 K$ q# N' h
    , C$ W) I1 w9 Q$ e. V3 j+ W" H( g3 q
    选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    ! n; d+ v" [. z' C : {: L, |; S5 Z$ |
    如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
    # O) Z/ o% D  l# i' [7 a
    4 y8 o0 `$ U/ m3 u. h2 l
    5 \! B/ q5 L4 ]" ^% T1 ]" j刚开始我也以为不能用,后来试着编译了一下,竟然可以!
    - `# f5 u) g/ o# |3 b
    1 \2 ?- F8 Q7 s9 _3 E6 z
    - p; r) F, Z$ h0 Q/ T6 FDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
    ! C% r1 T. i9 U! o
    0 [& G' h' J! `) q% J
    + |+ ]0 L7 r. C; D! U编写c/cpp文件: b. y/ @, K6 q( b9 {+ ]' v

    8 z3 Y" {  N7 }  a  A/ @( T' l与普通的C文件的编写有两点不同:
    # H. h% N, `7 ]# A# W" H( @* `) a. n
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。
      * |: }7 ?/ u* U+ k8 e& l  d
    / d2 J  V# P1 I
    下面以一个求和的例子说明:
    , `4 q' |7 j, e4 w; c8 `) L+ u
    1 }; x" f! Q3 H" Y& `/ _#include "mex.h" // 使用MEX文件必须包含的头文件6 D2 ]) C0 @* c' ~
    // 执行具体工作的C函数6 g9 e( L; @/ [0 @: V6 e- B
    double add(double x, double y)5 h/ V/ E$ m# `2 \9 {/ w% n
    {
    ) @" I9 e/ {3 X/ [, t    return x + y;; C- e. @( t- O7 M
    }! x4 N) e0 R; K; }# F' c: c
    // MEX文件接口函数
    5 @% }9 u- @7 [4 ^# tvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
    . e0 `( d; J0 r8 G6 S{! y6 ^& T4 j4 H. S% k& N& q! D
        double *z;( {* \8 a0 `7 L  W
        double x, y;
    ( X9 K# O' A* Q6 m* \  b9 h, q    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);4 b2 A; V1 @' n' _5 B' a/ O8 b
        z = mxGetPr(plhs[0]);) _. D3 w- j/ y/ w" s/ i: h
        x = *(mxGetPr(prhs[0]));8 }  i+ f) R9 P5 Y( Y5 d2 a  f4 }
        y = *(mxGetPr(prhs[1]));2 U; ~( C8 }  }- h. Y* S
        *z = add(x, y);
    4 ^4 d, u9 U( m$ Y9 }$ B}# ]( M3 t; C2 L3 l
    , F1 g! D+ y6 @) j. R
    / W: F+ _* d: ~9 v6 G
    Matlab命令窗口输入mex add.cpp,运行结果如下图: " s  U7 y3 v1 ]  i$ D% Y
    ( w9 q+ S  [( X; P7 Z1 S6 W
    0 A* g: g. c" B' @- d6 k7 x
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
      T% Q. h( ~) {# f- d7 w" k% T0 D0 i& i4 Q# L' @6 q1 `5 d. f! k/ n
    mexFunction函数介绍
    5 H+ o4 v  M$ {! C$ ^mexFunction函数接口如下:
    ; Z3 r# n" g: o+ D$ D' _" ~. u# z( J; i& D
    void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])  v0 i; O2 P% c6 \5 k) J
    & H! J/ A3 |' n3 B' H. [2 U
    可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:( D3 |5 k, p: {: r& i, h

    8 _& l6 I( z8 G3 e1 ?参数        意义        英文全称        类型
    ) w% Z: U6 ~1 h0 Lnlhs        左边输出参数的数目        number of left-hand side        整型(int)
    ) O/ D! k$ o5 u. q  tplhs        指向输出参数的指针        pointer of left-hand side        指针数组
    . S+ R" @) `8 ]4 G8 G( ynrhs        右边输入参数的数目        number of right-hand side        整型(int)6 e% P  U, B. E6 p
    prhs        指向输入参数的指针        pointer of right-hand side        指针数组+ q  H0 b* [4 P+ {
    详情参考:* u; S7 R% n9 O6 E5 d. B9 ?" X7 _

    7 q# |4 K: F# [Matlab参考-MEX库
    . R* X2 @6 h9 V" S8 a! ?3 _7 Q* D: r
    5 j# m! S3 b: }  c, E4 vMATLAB中mexFunction函数的接口规范(转载)
      P  h# k* S1 q( R$ s' y; F) u% i! w& |: p/ f
    Matlab与C语言程序的应用编程接口' E) W7 b* y! D: ^
    8 C. e! k+ N1 ^
    matlab和C/C++混合编程–Mex3 U  ?6 o8 M! Q' E

    $ [* i4 M5 A, n5 c+ e编译多个c/cpp文件
      }9 r! _6 T' Z1 ?! D* ^假设A.c调用B.c,B.c调用C.c ! _- s/ E. e0 h, q  D! {
    可以使用如下命令编译:
    : D0 r) [0 j# f/ D' s0 [5 W% g0 v6 e& i+ D1 T
    mex C.c
    5 t* p. x, O6 B% |mex B.c
    5 @+ E; L( V( W, H) ~8 A" [mex A.c2 o9 b7 e( }* G: s+ h& [& D. L$ B, a

    & ]! p4 x" V# ?" ?4 z- L! T* ~) _. }
    或者% [; A9 ~/ M( g" Y+ \  K' s* }5 J

    & i" z$ L: ^" ]6 I( s. N' Nmex A.c B.c C.c, Y4 Y6 m" s. \. s

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-1 08:14 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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