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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    . T1 ~1 L* o2 n2 {& H1 _# z' k
    说明' G% h: e3 [: ^! G$ Z  a/ O  ]
    Matlab混合编程
    ' r0 o; V" ^% K, C& S! X% d/ K( k下载与安装编译器- b& p: Q7 Q0 O
    Microsoft Windows SDK 71CC
    0 n# i! j. W+ w3 `5 R* BTDM-GCCgccg
    6 c; D" t& T; `" q3 C: K% ~" eFor Matlab 2015
    5 Y; A. n5 _6 ]* _+ YFor Matlab 2014
    % X6 n: k' J4 @8 \选择编译器
    , J% ?( A9 g) k* p编写ccpp文件/ P" K* x" t5 g
    mexFunction函数介绍
    " a3 r. ^6 [4 X/ o# x编译多个ccpp文件
    4 o: V! p2 v1 A5 U  c1 v! y一些实例
    ) M' _. s, q6 Z  s6 f  r/ \MATLAB2015编译MeanShift: \8 z$ O& B9 D* t+ Q! H
    ProblemSolution& z2 X/ u7 i1 \6 |. ~5 c) U
    找不到编译器或SDK
    9 {4 H' Y7 t8 eProblem8 B$ D# f+ e/ z$ P+ O' f
    Solution6 B  |* K  O5 I" d# `0 c
    注意
    4 ^, n6 M. ?* ]" Xerror C2143 syntax error
    / t9 a8 i* W7 v# J1 l& Y; I! uProblem
    $ s, D0 `/ Q& [- b0 rSolution1 @# M- n$ Z# ?+ k& [5 ?: b/ e
    一些有用的总结! Y2 Z6 v. u( W* }) `% J
    注意系统平台和文件路径
    8 a- i( s. |) C8 p2 z- e5 m运行效率对比
    - L) u+ r+ d- C/ R( |说明
    $ Z( _" D/ P% ^: b3 V9 u6 B记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。! j8 B2 e! }- H2 g
    4 d5 Q/ _" U8 k2 D; P. ?% I
    • 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)2 @5 ~& |; J1 _: U
    & U8 ?" ]/ B$ G  a6 `1 x

    & S# K5 H  q% R8 K% h% vMatlab混合编程
    ( y5 W& B# R: p3 `! X下载与安装编译器
    / A5 O1 V4 c7 ]2 HMicrosoft Windows SDK 7.1(C/C++)6 \! [: [* D+ ^) N$ Y6 z3 d- L: E
    点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。' e5 e6 v' ~) T9 t

    ) w* Y+ c5 q! c1 q, }2 B( p1 _- X; e下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    4 t" r! I& ?0 j7 P- q5 z
      w$ K$ t0 E, H$ n; j; y& n3 {TDM-GCC(gcc/g++), `$ J# H9 ~: t1 |
    For Matlab 2015
    $ w8 h: X' I9 {6 oMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
    ) o7 p  W( U5 y9 ?' Y. d" Q0 Q0 i/ u
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
      0 N( M* l2 x3 W

    + ^  H! k3 Q! O( S  D  e
    • 然后,还需注意的是安装路径不能有空格;7 T/ h; V7 `1 a0 F
    , F! Y) }- q. t% e& {
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:
      4 p6 q" T9 M3 d; c' I

    + \; k! S1 G6 Z! r6 t" k7 j至此完成!! `3 J( }6 ^% |- w/ u' C" J  B
    . [9 i6 @4 O7 p& w- D; n
    7 M8 a4 {9 y  ]) O5 m6 n
    For Matlab 2014$ t% n* ]1 K1 e& b+ ]
    如下文章针对于MATLAB 2014a。
    8 j0 @! {9 i) v8 ~8 R
    4 T' Y+ h- a3 @7 z点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
    / S$ H8 @4 K, e* d) L& t
    * a. H& S4 [7 ^  z7 F# ]3 z: \& \根据以前使用经验,安装路径最好不要有空格中文。6 J" C; t3 n6 h+ M& l

    7 f& T$ `' U/ \5 Y7 Y安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: * n3 M/ g4 q6 }3 r8 S

    ' T! T" x* H  i: ?! {/ h, |9 f  a6 d9 ^# K8 P& b  @9 @
    最后的战斗: 8 y- ^& i/ r. y+ o
    因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:' v& R+ u7 J; O& q) ^

    ! U# ?+ K: d- @7 I6 G2 G下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。7 ~) m9 u, H: A3 h, Q2 Y. C) c! |
    : S. r+ L8 ]" j* O
    在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):& y: s) x( ?/ e/ d8 U% {; s# y; E- P
    3 L- n3 q/ h* T
    %USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
    6 N" Z- k5 ]; C$ D- H6 C# s% Q* U
    下面是代码:
    , S8 O4 h: P7 Z4 r5 S  V0 h" e. N% {2 P# i3 \& R( l
    @Echo off
    1 S+ B/ }* N* F6 H5 {5 t: z6 ~7 Q0 l) j8 Q  d' j+ {
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX- Z3 a1 g& U- ~8 Y5 y
    ::       parses it and only understands a very reduced set of commands:
    & y+ c1 E+ G3 Q1 P# _6 u2 `; _$ U0 w::       "set" and "rem" apparently, everything else is ignored (behaves as
    & c7 Y6 `7 n* B( l" S::       "rem"), so don't do any fancy batch stuff in here. There are some
    7 j* ~6 s3 F  j7 Q# y0 [+ F::       undocumented special vars you can set here that will trigger MEX& q' @. F$ b, z0 B
    ::       to do fancy stuff.& z6 c5 N- ]" y6 m0 m
    / `. h/ \, m, h" H( _( l
    :: You can use MinGW64 builds (win32 threads + seh unwinding) from here:' V+ H% l7 t* ^: k8 C
    :: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/& n; ^6 G) n+ o0 j" U
    * F8 e# @3 _' M9 Z! k
    :: Tested with the following:
    % G6 Y( b) u5 x/ W) n7 q. 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
      E% E* ?$ y: N* [$ A' `
    ; p$ ~8 Y; C" C' p:: Set this to your Mingw64 top folder, where you extracted the above, }2 \- D2 Q1 r
    set MINGWPATH=p:\mingw647 r! c5 Y$ n' q

    $ H- w% k- X0 t5 X8 p:: Leave these alone unless you know what you're doing.
    , [+ ?. C8 O' y* W( G1 Bset PATH=%MINGWPATH%\bin;%PATH%
    ( x7 h" H( ?1 \$ T! d5 Lset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs7 z" e* Z6 f$ v- [4 m  D- }

    4 B* s0 B8 V. ~7 u* a; T5 P:: You can have MEX run some commands before calling the linker.
    4 R: a: B- l; _. J1 ]. h:: The two examples below will cause gcc to output the full path to some; ]2 Q! ~  F- \; i3 d1 |3 P
    :: static libraries so you can link statically to them (see the# p0 m' }! v# f
    :: LINGFLAGSPOST special var below). You can set any command here, however.1 l8 p! z9 `; Z# {# x& T! n: i. N' L. w
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
    " J2 h' q3 K* Erem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
    # C8 z( A' x( Y: z# O0 h( [rem set PRELINK_CMDS3=...
    " C, B! x  v/ G9 g6 J$ H% m4 J$ Q, n- p& w% ~& }
    :: You can have MEX run some commands also after calling the linker; U+ j5 h( o' \7 h0 M. U' ?
    :: (e.g. upx compress the output .mex)" Y- S+ v2 I7 N% h  v
    rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    / n# M6 {# V" {, }7 ~& Prem set POSTLINK_CMDS2=...
    ! H* {4 q  k( S& u* @" \$ |! s  U1 K3 ?2 ^! U
    :: You can change these if you really need to.8 S' X5 s! y. R* ]) h4 n
    set COMPILER=g++& ~# ~3 M) z+ u1 }
    set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE1 j6 P+ A2 p, K) f2 q! w7 s
    set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
    0 b- O3 p& Z9 o7 E! r9 Oset DEBUGFLAGS=-g
    0 A- C3 m7 K% S: P" M7 ^set NAME_OBJECT=-o
    5 s7 R3 X5 l2 r' w/ `
    8 o$ N  l: i' [5 U0 t! aset LINKER=g++% f) t' \7 q! f% {. y% A
    set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas3 G6 L3 [& h5 S. g- X

    2 @0 o; T, O% S/ z$ X  X1 Gset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    % @5 s* n* y: O/ D2 I! I+ N$ \" |" kset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"3 |) F8 B0 S- V
    9 M3 O, Q0 x/ J5 g7 \* W+ E
    / M5 S# g6 \% x" h
    :: EXAMPLES* c1 M* U! E9 d7 k
    :: ========
      P1 x' V) O5 X* m3 n( ~5 I4 F
    9 D- X# B1 X/ U0 V:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
    6 a( v+ n/ ~1 _8 ?, _% r% o3 ]% T:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.4 P+ k6 T, y# F% Z& c
    0 g: B# C6 g& d( V5 m7 A4 P! e
    :: To add include dirs, lib dirs, or compile/link flags, do:! E% X$ ?& y1 K+ E- s$ s( W: |
    :: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp" I1 I" k) o' j; @6 [' U
    " j5 t' v5 C% |5 W; |: W6 R" j

    $ v+ ]. M" o& m/ g4 ?" p选择编译器
    1 B  m* n; V; f: X7 W7 H查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    & P% H9 u' _1 M- q- _3 r  r& F
    ' r* m# {) e6 j( k  }; ]+ [选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    ) }) D* g8 E, `& W3 q   ~1 J7 T2 x# E2 _# Z
    如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: . t& H! i/ ?5 t# i+ x1 A% r! [# \/ |# n
    8 y" ^* l& K& @# z, m! y* H9 V  Y
    ' K, x6 o. ^3 B8 ]3 _* U- Z$ r
    刚开始我也以为不能用,后来试着编译了一下,竟然可以! " M6 t( P3 j  e0 D

    7 r$ z. M3 D5 ]# t! q7 G3 c  e% u0 Y- f
      ^3 U, u2 F; B# _" U0 h6 m0 XDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
    ( X6 h6 k# [% M/ c5 B9 C- {' T1 V. s4 a) R' m9 _

    ! f" u$ [3 p2 P8 h/ z) r  L编写c/cpp文件
    ) {' \- e% y7 |+ _6 |& v
    3 v( K" F; \4 p; m( T( e* \与普通的C文件的编写有两点不同:
    ; H0 ^* h2 z- L# p6 R+ M$ n' ~; S9 @! n& P' R
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。6 z/ I# w# R8 b) D

    / J3 J5 p* y9 K# A, [! U下面以一个求和的例子说明:
    $ |9 m: H+ |$ s2 j2 ]
    , l5 V1 ^; M# Q' L9 g6 l, [: A. b#include "mex.h" // 使用MEX文件必须包含的头文件/ d6 w+ z0 H. {
    // 执行具体工作的C函数( Z( U+ r2 ^" B* x4 u7 x& k# q
    double add(double x, double y)0 \  @, _+ g6 s% c; a/ j$ T6 v
    {) N5 A  W* p& L# x
        return x + y;
    , l$ {" u( e1 ?  e$ p: F6 o# {}( ?. s" _8 I- Y& r
    // MEX文件接口函数0 `8 }; s# d0 f; h3 B
    void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
    " Z- ^, `! g% D/ E, O{1 r' r" q/ f% s% D/ z# p- m
        double *z;2 V+ G2 l2 G1 t1 @
        double x, y;
    9 j3 y6 {4 o( p5 j/ q. _- o* }    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);7 [7 a: {1 O, k
        z = mxGetPr(plhs[0]);
    5 o# b0 a. n0 S; p9 \7 d0 m" f7 w    x = *(mxGetPr(prhs[0]));
    1 D4 N1 U4 H7 b: u/ X' ^    y = *(mxGetPr(prhs[1]));8 Z* I6 o. z) w2 S0 q4 f8 a
        *z = add(x, y);1 d8 R+ N: Y) w3 r! P
    }1 ?. ?6 x* k% O2 I2 K1 z9 f( L
    / R. p. A: ^1 G% c4 v
    " n, h& ~" N! u; d$ q+ s
    Matlab命令窗口输入mex add.cpp,运行结果如下图:
    1 A1 r$ s# c# O: c; S
    7 `  D, X/ i  I  a
    , f. o4 r4 X( [% ]' B$ d在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。; @. v. k- m% _/ D
    2 P7 b; w; F9 D4 Y: z; y' v* [5 W
    mexFunction函数介绍) n% Y0 y$ {. ^
    mexFunction函数接口如下:8 {- h7 a# T. Z2 ]( [4 s7 z" i3 R

    1 B% S3 `1 v$ |) Q! Yvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    : d7 ]; _$ R: c' i
    % M2 R* o2 \' w% a/ `& k, W可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:$ P/ h; W- G$ M* o; A
    * ^" U* e, d) n/ Q" i2 b
    参数        意义        英文全称        类型
    : j; n+ R/ k( K& b4 {$ Rnlhs        左边输出参数的数目        number of left-hand side        整型(int)8 Q- M9 x/ ^% M; T4 x: |# b
    plhs        指向输出参数的指针        pointer of left-hand side        指针数组
    8 R" P8 B- e& g- qnrhs        右边输入参数的数目        number of right-hand side        整型(int)
    6 q; e" V, R- ^" S7 }prhs        指向输入参数的指针        pointer of right-hand side        指针数组, F9 v6 ^! N) v7 E( G4 V/ S1 Q
    详情参考:$ v$ I6 W" |+ t9 {. G, G% |, G) E& F
    & @( ]7 X# {$ N7 E4 q# @1 v
    Matlab参考-MEX库; d4 K( I) p/ k
    # F" L$ A9 H* o* j% z  }2 f# b
    MATLAB中mexFunction函数的接口规范(转载)( g: N" v. ~5 g9 Y) U
    8 g) Z- D" u5 s
    Matlab与C语言程序的应用编程接口
    ! B- s# k9 Z7 R$ k  Q  q1 W+ q9 `. U' u6 a2 t; f
    matlab和C/C++混合编程–Mex
      k! ^* c2 n* a! m
    7 ^$ x7 E1 L, i" c' k编译多个c/cpp文件
    : w* t: u2 }% U假设A.c调用B.c,B.c调用C.c
    5 T6 Q8 _- J$ S% M# l可以使用如下命令编译:
    : R3 M( O; G+ ~! b# X& M# }9 r" ?& J7 s8 ?" Y
    mex C.c- m3 R& z; N. j
    mex B.c) F! X* h* {. a$ W4 n2 }
    mex A.c
      d" j) @3 j2 k, y8 `8 G# W6 q" _# g4 `, E
    - P0 Q6 O; N1 ^6 c) M
    或者8 A& p6 C  m5 H7 I. h/ s: J

    . }( W. t- f6 p$ Hmex A.c B.c C.c$ ^. T# x8 X2 M; ]0 \

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-8-2 18:26 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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