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

Windows 64 + Matlab 64 MEX混合编程

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

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

    [LV.1]初来乍到

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

    EDA365欢迎您登录!

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

    x
    * |$ m' _& }1 g' s( @
    说明
    $ H9 f  u6 Z$ |: M2 \6 ]Matlab混合编程; v1 U& X' d$ g/ a/ U
    下载与安装编译器
    + y* w1 p1 o$ O. y8 w7 UMicrosoft Windows SDK 71CC2 c6 s: L4 T2 u7 S' D- f
    TDM-GCCgccg) z: a" z2 k/ b: ~
    For Matlab 2015
    & H+ t' \' M3 e0 n0 f% `* mFor Matlab 2014
    8 A$ B" ~5 k; F8 [  L' L选择编译器
    " i: R# u. K- t编写ccpp文件
    + B2 l' A- x2 V) Y  V# TmexFunction函数介绍
    ( G: h1 ~$ Y' k0 z, i) H+ h. B+ x+ i编译多个ccpp文件  F" I! \/ {  ^4 W' J9 W
    一些实例# G: x! u- _, R$ Z
    MATLAB2015编译MeanShift
    8 M7 x* a4 l3 ]+ M) J, KProblemSolution
    7 f0 _% e9 g! y- R6 _找不到编译器或SDK
    + X4 {3 E1 y+ Q: ?- \( dProblem: J4 M8 ^7 A. v7 P: j
    Solution
    0 s& M7 Y% x) J# p+ K! I+ p注意
    7 U' N+ C8 Q' Q5 F- j; d) Werror C2143 syntax error1 h6 w( Z+ P2 j% u# j
    Problem
    8 a! D9 ^, l, tSolution
    4 N' {% U2 h5 {: @, H) q8 H4 F一些有用的总结
    * f0 K( z6 t1 |! c注意系统平台和文件路径
    9 g- g* m' F% P9 U% _6 r4 Q运行效率对比
    : ^4 K& `6 j( E# P. F) X9 p说明5 ], G7 p1 o5 L* h) u- l6 c  X
    记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。5 N) k$ `$ [3 a" u
    7 g* U( s+ w% N) H
    • 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)
      # P7 v) W/ R& d# }& S3 v+ W

    . o3 h# M( g% ^9 N9 p
    ; m) m1 V% |4 S+ V0 VMatlab混合编程
    % C4 L( d3 t5 T8 }下载与安装编译器* R8 ]! h8 N4 @6 l4 {
    Microsoft Windows SDK 7.1(C/C++)
    ! w6 G6 \5 W" z6 p6 `* |, S点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
    8 _& R4 S0 G  Y% v, J! h8 I% K0 \/ l4 B7 S7 I; e5 g
    下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
    / F: [6 Z# j" m2 @' e
    & j% o" T3 m- V' G# OTDM-GCC(gcc/g++)
    6 z  J9 q, G5 x8 T- k/ OFor Matlab 2015
    . F7 N% r' H8 X! wMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
      M( r5 C( R& L
    7 i" _* v9 M/ Z& S$ |2 e
    • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
      8 P. K  y$ F* ]: N
    ; M4 t, j. I0 F9 O/ I) H- J
    • 然后,还需注意的是安装路径不能有空格;
      5 K) c0 R- M9 r& f: F$ E6 \5 q
    & l8 n" M# X9 X  K  h" }  G1 l5 G
    • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
    • 重启系统和MATLAB后,输入mex -setup显示:
      6 x- ]4 ]3 z! y% P  f  a, O+ r( m9 c
    ) y7 z* z. d. p  ?1 W/ C) J
    至此完成!5 r. E. Y( j* X/ o  N1 ^
    9 f3 H/ P: o/ k6 f3 f

    + q, J9 ?  P* ?! z- xFor Matlab 20149 L! H9 _6 E( x0 [
    如下文章针对于MATLAB 2014a。) e% |5 ^5 ?8 E9 o
    ; E8 t5 P) R1 c0 b# l1 f
    点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。2 E* F0 @; M5 ]5 Z5 f- y  |
    % i8 l' v3 N# k% F1 r
    根据以前使用经验,安装路径最好不要有空格中文。
    : B/ \! t8 ^7 _- t
    4 n3 L/ N, Z3 ~' n+ g9 \安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
    0 R1 r8 d& X6 c% _ 2 |; B. a# L- O, U) Q. v
    5 q5 i, L- E! T( Y; @& `
    最后的战斗: + v8 f( V& ^1 C' m$ H( k
    因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:9 c" s' D; I: T. @7 J- r, S6 F
    0 f+ K! n3 n: O2 G0 }, E2 p( A" D
    下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
    5 z" l, x* o& _8 z. a& p% ?; ^+ Y
    7 y! M2 p$ n  @0 C, Z在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):2 e. d$ c$ l7 J# e

    : f0 K/ U* n2 z8 a3 A: n3 m. F%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\( V- ^# Q; H  v
    . H& C& ^/ q. U7 W
    下面是代码:
    & g6 l2 ^3 h$ {
    . P- G3 m. e( V  k# R8 L@Echo off9 G; X& {/ }: K
    : a; L  R' a$ O. i
    :: NOTE: this is actually not a proper .bat file executed by Windows. MEX
    " O: u8 t, P9 r4 E; [4 e::       parses it and only understands a very reduced set of commands:
    : p' a' L  C: T::       "set" and "rem" apparently, everything else is ignored (behaves as7 e7 h& K9 k. |9 l& z5 @# E
    ::       "rem"), so don't do any fancy batch stuff in here. There are some, M. B* _2 v8 s
    ::       undocumented special vars you can set here that will trigger MEX& Z7 C3 U/ H; d
    ::       to do fancy stuff.
    ! X1 k  i: ]; Z8 k0 V: [& F# A8 X# X/ r5 f# q# X
    :: You can use MinGW64 builds (win32 threads + seh unwinding) from here:% s& m! j2 o7 g" o
    :: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
    1 P9 @- |% l0 d' j, ]* u9 W6 s  K5 B! D1 j( N# e
    :: Tested with the following:
    0 \1 Y; A) g* k9 W8 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: A" s" W; ~& D' A' u
    0 ]6 E2 o" n% ?# W, f+ q:: Set this to your Mingw64 top folder, where you extracted the above
    5 n$ N5 b! k% j  C, g0 j9 yset MINGWPATH=p:\mingw64/ K  e/ T6 w+ R7 D/ N0 k3 @* r% M: M

    8 A7 N" e3 Z3 _! G6 @. K:: Leave these alone unless you know what you're doing.
    2 t7 r& G3 V4 v. o. w: S- ]4 k9 O3 s5 ?set PATH=%MINGWPATH%\bin;%PATH%
    + Y5 z; L3 }: }) xset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
    : V# Q) R  A- x* [1 t8 J
    % a8 m& N' J# a  X. U) z:: You can have MEX run some commands before calling the linker.+ o! s3 W5 s* `, }/ U
    :: The two examples below will cause gcc to output the full path to some. a. C  \5 T1 x: ^- X
    :: static libraries so you can link statically to them (see the
    , K3 X/ J+ I  ~/ ?9 N6 O: b:: LINGFLAGSPOST special var below). You can set any command here, however.9 ^, \, ]: l9 }1 e4 y2 H5 J, v5 J, w
    rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs9 L; W' P7 B6 g) w0 `) n
    rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
    7 Y$ D# h6 P3 E, X8 c' brem set PRELINK_CMDS3=...
    & Z# l8 K$ v0 J
    ; [. Y/ W- U5 R8 W:: You can have MEX run some commands also after calling the linker
    . q4 @& P3 V5 @% ]4 i. o$ c:: (e.g. upx compress the output .mex)
    ) ]1 J* _; ~, i8 Rrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    4 T4 T- S5 v5 hrem set POSTLINK_CMDS2=...
    2 _: Y6 X+ d2 y4 W3 u/ N8 m5 O. z* Z, \# d& [8 T9 S: F+ N
    :: You can change these if you really need to.5 u) {; z8 p0 q  ?" \# P# z7 [
    set COMPILER=g++
      Z- W4 A2 u. L' sset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
    3 r* a5 q- _' j- C2 iset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
    # l& ~' F1 \/ G$ q9 cset DEBUGFLAGS=-g$ ~# A/ H% I+ A' v! D' `& i
    set NAME_OBJECT=-o
    2 @+ `. m. H7 D/ C3 Z2 B' a
    8 [+ j! `( x6 w$ |8 U) h% sset LINKER=g++
    # T* M$ z  Q' k8 O& W# vset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas& B3 U+ K- [+ ?

    , W/ B; Z* i8 U7 V3 i5 [& S2 lset LINKFLAGSPOST=@%TEMP%\mexstaticlibs
    0 S$ H( w% b5 S0 pset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
    ' w% o$ u+ G" e: }* h" N& [0 U2 d/ [) w/ s+ X
    ; u: t* S, c2 B- x3 t6 E
    :: EXAMPLES9 u  t  }7 \" s0 \1 B
    :: ========' m% k6 n" M& r8 P( b

    " A4 [4 w6 C4 I" S" D) a  k8 e2 J:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
    7 M0 i; m2 M" ?:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
    9 C; G& P5 s- P+ [. Q3 B! [6 ]1 i" o1 j" ?; g/ G4 a$ Z
    :: To add include dirs, lib dirs, or compile/link flags, do:
    , c/ O! M8 d6 J9 _:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
    . R1 \" [( G4 |, O' l7 r0 ^7 _" Z( b4 ^! s! U1 n8 {4 j, n3 G

    % r4 S. H; C: p$ `1 v9 z选择编译器
    1 |7 r# D  @$ ^; i( F8 q查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    9 l- _3 [; Z0 {$ A# M4 Q6 \8 k
    3 J( z/ |' \8 W4 `选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 6 Q6 F$ e6 X9 g6 k9 f1 U

    , z+ Z1 l) d3 {如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 1 d' S$ t7 e6 m$ C2 h6 G  y8 |

    " S4 b5 Q' W$ H( m( u
    , t0 k, N- Q7 A  l5 W' D8 B& I刚开始我也以为不能用,后来试着编译了一下,竟然可以!
    7 H: m3 n3 }( Q! U1 g; o
    8 h' D1 Z+ G( s( s! h, k
    0 v9 y8 c5 w% d+ l! J. KDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
    " T; V1 W4 [- e, }* b3 w, j) n7 w5 }# d: O

    $ Z5 l( n5 N" `6 ~4 ?6 F( r编写c/cpp文件
      {+ u& Z4 [* |. r" a
    % w) {7 \) ?* z0 y- y与普通的C文件的编写有两点不同:% j' {/ F% P- C( r4 Z2 A

    8 k( g+ X* K) l
    • 包含mex.h头文件,即:#include "mex.h";
    • 编写mexFunction函数。. o9 P" ?. |4 O$ S* T
    - b: t2 ~" S) ?/ X
    下面以一个求和的例子说明:3 _: ^+ u( S5 U" b
    4 ^/ J; K5 T2 C
    #include "mex.h" // 使用MEX文件必须包含的头文件
    / ~; w5 P: W# t( n$ b4 _6 E1 w// 执行具体工作的C函数
    6 M( A$ @) Q6 y/ W- G7 b+ V. idouble add(double x, double y)
    ( w5 w8 V0 D) e{& S) W4 c! J; o8 S2 h3 G& ]+ O6 Q) \
        return x + y;
    $ s8 n4 A3 }7 p}
    : g: u: C) T* Y& Y6 {// MEX文件接口函数+ r; M5 u! x% Q( U7 I) i! t; |# s' q
    void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
    / ~8 ]: h, E7 S% X% N6 K3 y{
    0 |! m( N# f$ i1 l0 w    double *z;
    - F; v# k+ y: I0 d6 }& ?, a    double x, y;
    , `, p, P8 G. n  ~& ~8 c9 e    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    " f# y! T. l- Z: A& w5 @2 G$ p    z = mxGetPr(plhs[0]);
      E9 z( [) c9 v5 o4 f    x = *(mxGetPr(prhs[0]));
    7 t' \( v. d/ x9 Y$ w2 z    y = *(mxGetPr(prhs[1]));
    & V, z9 _8 k# G* F; [: D    *z = add(x, y);
    , O& i" B& D5 B. ~* @}
    + x$ S( z5 W' ~' ?! r+ z, L6 M3 ^+ [
    3 Z+ Q/ T% v8 w8 w2 n8 S
    Matlab命令窗口输入mex add.cpp,运行结果如下图:
    ! G1 f2 {2 e: U/ v' a& r- w/ p ) e& ^+ T2 w! ?
    ' ?* ~1 G( A6 o5 _/ X/ K' [
    在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
    7 i& e5 w) i5 p
    7 A* S% Z  @) ~" nmexFunction函数介绍3 D7 @( `. B) V9 k6 e, H% z
    mexFunction函数接口如下:3 O4 N' u1 W$ C

    : [3 g& q; v3 U( M% k$ Cvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
    , @; ]! q$ }) U) d: Q9 f& |/ Q$ C& [8 M# ~
    可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
    * C6 u- K. X# _* I3 H# }4 Y5 u! i' k  G+ ~2 j4 q8 i
    参数        意义        英文全称        类型
    ) V3 m! b5 x( X2 C* u- |- X8 xnlhs        左边输出参数的数目        number of left-hand side        整型(int)
    9 G3 i! d" v# x5 U8 p) Q8 Y: lplhs        指向输出参数的指针        pointer of left-hand side        指针数组
    / w6 M, j3 L6 K, vnrhs        右边输入参数的数目        number of right-hand side        整型(int)
    * ]3 [3 u/ Y* e# S0 iprhs        指向输入参数的指针        pointer of right-hand side        指针数组0 m" J( n7 h$ }9 _% g5 p3 q
    详情参考:
      |- r* D" H6 ^3 K& a4 O1 l; V, I, l: _  D  @
    Matlab参考-MEX库2 }1 y# f  }( N3 u; n2 R

    4 }& q# O# e7 V8 ^# l* c3 h2 kMATLAB中mexFunction函数的接口规范(转载)
    ) {! m; Q7 C9 x8 w8 j$ p. m  D4 ?8 O% N
    Matlab与C语言程序的应用编程接口
    4 h2 z: X2 d) @+ s
    7 W7 P& `5 D. e( x: dmatlab和C/C++混合编程–Mex  L* h, a! X% s/ [
    0 d6 V  E& w% i6 i  x
    编译多个c/cpp文件2 g/ w0 J* }' a, w9 d) |
    假设A.c调用B.c,B.c调用C.c
    1 c; D  a" k2 V可以使用如下命令编译:6 |6 M$ a- o& |% p' z& {; T

    ' W1 A) y" a% D$ lmex C.c
    3 a  C3 _. e$ t3 J! N- j, C' D. Fmex B.c
    0 m8 [- M/ i( @, _. H2 ^mex A.c
      s* J. i4 I& z* b) Z/ R8 D
    8 h4 J; \' W2 D7 a5 k: F4 k& ]7 y: q, G7 H
    或者
    $ q: [+ S0 ]$ G+ b0 J- y/ U+ G3 }( }$ N
    mex A.c B.c C.c
    " a% T8 J, k0 ], s7 w8 s. V) v/ X

    该用户从未签到

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

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-24 07:15 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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