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

Windows 64 与 Matlab 64 MEX混合编程初步

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
说明
" l( W' ^, t2 FMatlab混合编程. z: O% J7 q/ c, r$ G/ Y
       下载与安装编译器
, ^& P( x  y. n: i7 u2 C- `              Microsoft Windows SDK 71CC
- ^8 L9 N+ v: X              TDM-GCCgccg, r- N5 G! h8 w
                     For Matlab 2015) O+ R, Y& t* K; M, i+ b; y
                     For Matlab 20147 y7 E# i/ k+ Z% Q: \9 `
              选择编译器6 a6 K$ B5 E( v0 }: d
              编写ccpp文件; G9 f1 B  ]; N# q) M$ w
                     mexFunction函数介绍
* y8 i/ N5 A& F8 u0 n              编译多个ccpp文件+ H7 \$ R3 e, |) P  R, `5 b- b

6 k: d  s4 h4 G' N9 p9 e6 t3 B, I% J' H  v( R' ]; U- ~- _
说明) p/ o! u9 x( Y- x
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。. n! y  N. m" b" I4 n
+ a# [( N, [- [$ \$ Y, u  Z
  • 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)
    ) R  {# D$ M2 ~& n
) u1 a, K7 [8 a; G) i1 F
& {2 o  H, N3 h$ m9 n+ G

1 L4 v5 S3 |, h# Q+ Z: r. C4 h% j: lMatlab混合编程
- `3 c- Q1 v0 x. g" G0 A下载与安装编译器' F- t/ ]6 d( x! ~2 n% C: t
Microsoft Windows SDK 7.1(C/C++)# J% F; T6 b0 y. x% h
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
. f9 n2 E7 y; J: V* d  K9 Z+ J
) E6 ?; f, b& u# a下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。7 a, P- j( N. Y4 F6 O
$ _6 B" W4 o% K" ^
TDM-GCC(gcc/g++)4 A) |/ t  n  R+ M+ _6 Q% e# \  R/ Q1 t* y
For Matlab 2015( ]; d$ C# s6 f
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
9 `" T& i$ n5 s+ l
* \3 G) v! z5 S* A
  • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:, S( s# q. ?4 B3 K6 X
' t% _1 R% c) g
. N) ]1 _  G( K* T

, H1 E' n; |& j, N$ T
  • 然后,还需注意的是安装路径不能有空格;
  • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
  • 重启系统和MATLAB后,输入mex -setup显示:% h+ _  X, B( S4 b! {' H2 o" h
, K. q- j% Z1 w* k8 t
; I& ^7 B6 j4 \4 R2 d$ Z& h3 v1 O

! _7 ^/ d2 l2 H5 z至此完成!
- g3 c3 ]; I$ c) F  q
2 f; ~+ Z: m, j- C. rFor Matlab 2014$ F+ r% ?  Q# p. S% l
如下文章针对于MATLAB 2014a。
. F8 c2 z3 W+ ~5 a. e
7 [$ c5 V) S. z7 i) x, }点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
, m% N3 ]& @9 R. s" P4 Y
; E$ [* P8 a9 {$ {9 g/ U/ w( `根据以前使用经验,安装路径最好不要有空格中文。* P" r: W0 j- N- C- K0 f
1 l: e! D- @* X4 _. Z* }- T
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
7 Q) @* [' l6 G0 y# o4 p
2 P7 r9 z' R: m2 k7 w$ u7 e
$ J, M5 z1 y. ]; y最后的战斗:
/ u4 F; _. H; y* l* c% g: [因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:3 y  v3 q/ Y7 k4 N3 c
7 l1 y* r: C7 X  h
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。. c3 Q5 x2 K0 ~3 Y& n+ n* O' c

0 ?; ], K% c% G8 A在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
  e6 O  o* L4 R( A# b( |7 ^3 y3 x' \! }0 |/ Z
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\: }6 E4 A% U; d1 `
% B+ a4 M+ C/ P4 G% s+ o
下面是代码:
  W# E# Q7 x, G, S1 }% `! D! I& R/ A1 F4 A) p
@Echo off- K/ u$ v: _2 q& |! b1 j! C

+ c* p* E: `/ p+ r' r:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
5 \6 T9 @: u' t4 u::       parses it and only understands a very reduced set of commands:, r) b) q6 b7 |& _, u" ~+ Y
::       "set" and "rem" apparently, everything else is ignored (behaves as/ L! _9 @9 \& f& @# u" z
::       "rem"), so don't do any fancy batch stuff in here. There are some
* m" n" o3 j/ T# }::       undocumented special vars you can set here that will trigger MEX) O/ d. n' J3 e! X: L
::       to do fancy stuff.
: _  T) s6 {4 p5 A
& }  z) v' s, v+ S9 c# |5 p/ T7 D:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:1 ?0 _1 }7 e  a$ j7 j6 e4 L
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/2 G# @8 v$ j; _' e3 l9 r

" Z) m8 a# F; Z6 L: R:: Tested with the following:
; X) w5 x0 G2 k. S1 D% a6 W:: 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.7z6 U8 X! E0 j, k3 {8 P
( A! H0 |) Z+ n
:: Set this to your Mingw64 top folder, where you extracted the above: g8 J8 j+ C" \- E7 z# a* R& R
set MINGWPATH=p:\mingw646 r4 ~) n4 @' E! e4 ]# ]
- P& @( T  H0 b: ~* w
:: Leave these alone unless you know what you're doing.& q! N0 D- [  Q2 K. m
set PATH=%MINGWPATH%\bin;%PATH%
- N9 n* w; Y$ O: T: L: hset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs+ l' Y$ g0 r0 A2 `' v6 J
; E' H$ u4 x: ~; e& l+ h) o
:: You can have MEX run some commands before calling the linker.
: [8 d. b2 q8 k% V! V2 z2 W5 r:: The two examples below will cause gcc to output the full path to some
& h4 X; V: }" S' q:: static libraries so you can link statically to them (see the% U& b0 f. M- a+ k' c/ B9 H5 e
:: LINGFLAGSPOST special var below). You can set any command here, however.# W, K2 \; e$ `: {% {
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs; Q  X2 }# ]4 b% u! p/ M
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
$ a* Q- k3 M) `- T! u9 B+ Wrem set PRELINK_CMDS3=...
+ x4 F3 N! b, X6 t8 I% s6 o" c& ^0 y6 p( w/ w! h
:: You can have MEX run some commands also after calling the linker
+ A' I" v- O) c& {+ n* n: N:: (e.g. upx compress the output .mex)
6 w9 U8 x4 M2 D* |3 b5 y& _# mrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"4 m# E6 c/ @: |, I, @7 [$ ^7 ?
rem set POSTLINK_CMDS2=...
, L+ L1 C! M/ @0 C+ G, |" P5 l: `5 w5 |2 b  B1 r
:: You can change these if you really need to.8 v( G. }4 s8 e. `: J7 f
set COMPILER=g++$ a( C+ E/ K* p+ k4 J
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
5 d) |5 M) I6 \5 g5 B9 N! Q* Lset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG# d5 P* ~" Y0 o1 k$ X, F/ y/ f
set DEBUGFLAGS=-g
( G2 X6 h8 K; }3 k$ \set NAME_OBJECT=-o
, E6 X3 `* n" L6 b' v2 t9 F+ D7 o5 M& E! L; k+ m' d9 H! }
set LINKER=g++
! B% j' O; F0 Y( o4 e/ }9 rset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
( w6 v. \: o  @+ I
8 g) _2 V- n  R: w2 Oset LINKFLAGSPOST=@%TEMP%\mexstaticlibs  B4 A3 A; g; N3 D" i9 u
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
, _' @3 Q/ J) d% P. }8 w+ ?! B" \$ ?5 D5 U+ |" m
1 v( ]$ P. G8 T0 e0 B- H
:: EXAMPLES
' v1 e( L+ _$ E: W6 ]1 @:: ========
' B' c* S% j* Y: b. ]5 w( n; E0 x- C1 @* I
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use8 }/ R' Q( n4 T8 @! c/ D
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
+ H8 D! Q+ i6 Y( ?: y7 J
3 c. }- j& f, p, H+ P:: To add include dirs, lib dirs, or compile/link flags, do:; E* u" q5 c; ^) B* s: }. ^' U; w
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
  A- @9 S0 p9 P0 h
3 \9 d  [( v5 h  g3 W) b5 A, |" B# D% o. O4 {3 z+ ^% {
选择编译器
; E; o2 G! w( t* @( _9 f# _
  • 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:8 Y8 e7 v9 J( E: T: b0 {
  • 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 8 |% S; G2 d; j  Q, q; H
  • 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:   \) L3 s; Z9 k' L5 r, G0 Z
    & o$ K2 A* {& h( Q( x! o
1 p; h- ~! e$ S& X1 k

4 u4 [+ V/ \. @' Y& U# g刚开始我也以为不能用,后来试着编译了一下,竟然可以! 4 K4 p% k  f5 U3 [5 v/ D$ I
       ) m- Y7 w) w: o" B% s
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
" P, Z, n6 [, t' o1 [- G# R
& E) |$ |: l5 l
$ u4 A, r! \! d  Y7 N8 k编写c/cpp文件
" }' i* H8 W5 ]6 @3 Q与普通的C文件的编写有两点不同:
: {; P5 @& o7 Y  a5 H: _" M# b+ P# _7 Y3 ]5 x
  • 包含mex.h头文件,即:#include "mex.h";
  • 编写mexFunction函数。" W/ c+ A( r1 g& V2 s

! h) R/ w* x+ {6 L( c% k- J7 |% U
/ M$ j- _% o& \" h2 ?, `5 M" n下面以一个求和的例子说明:$ y; e, q3 N' X+ ?' T
+ k" `3 e4 H. ?. v" g+ s+ ?1 _
#include "mex.h" // 使用MEX文件必须包含的头文件9 u8 v9 J& X" Z/ D6 I4 s3 |
// 执行具体工作的C函数
9 @' M6 Z( K) k: j6 q0 ]2 W, zdouble add(double x, double y); A4 T  Z6 ~  y/ j4 C4 c5 H# o! @
{
0 V" l% j8 o* d9 R- h4 T" X% g    return x + y;" s$ |" l: g7 i0 w$ x! Y
}
% x* V" U# x* N9 F// MEX文件接口函数& V; Q" H# X& l/ J# {( @
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])1 {6 }) [( R; B* B6 v7 W
{
) f& r# A) b- L2 M: U    double *z;
- Y4 `) H! C0 c    double x, y;
: B# a( x" f) ]$ c+ m    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);) I9 V! d7 @# V& X; G, Z
    z = mxGetPr(plhs[0]);
' ~; d, ^- P& H1 W1 \* w2 c    x = *(mxGetPr(prhs[0]));! s8 P( V# }% L7 I" e
    y = *(mxGetPr(prhs[1]));
  b0 E) n% l& {* q8 t/ R    *z = add(x, y);
  ?0 T% t! A/ K}
- f+ o8 S* a9 d3 l  Z7 t' y' j7 I3 p6 o7 g( E6 _: h% C! E

3 s$ R) `" ]8 e2 N8 f9 _  oMatlab命令窗口输入mex add.cpp,运行结果如下图:
+ P- ~: b1 |8 L, u  b- \ 0 q7 l6 j+ ^( o: C7 j
: I& u$ ]4 {0 o: C( L$ s# V/ D
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
; B! o2 l+ \4 T; o0 ^& w% V! t/ e" {8 H$ Y% R/ y4 N" }! D' _
mexFunction函数介绍, H3 g( v4 ]' q
mexFunction函数接口如下:+ ]1 h" W) X) x  z, N$ x; Y6 ]
  c9 \7 D/ ]8 J% ?) g6 ^
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
: j' C% r/ P  E% Y
8 }8 v0 ]% c( }2 _- C可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:8 }) a, S1 c1 p9 l1 l2 _4 {
; w; ?" D$ N  W6 u( _
参数                  意义                          英文全称                 类型2 @( S6 ~  A8 R6 L+ g5 Q
nlhs        左边输出参数的数目        number of left-hand side        整型(int)! }8 Q" l0 ^+ `- ^
plhs        指向输出参数的指针        pointer of left-hand side        指针数组
( ]1 ~3 y5 s: A$ R) R! ]; J* [nrhs        右边输入参数的数目        number of right-hand side        整型(int); ^) ^' w& T( G0 F- }/ H; P4 r2 c0 }
prhs        指向输入参数的指针        pointer of right-hand side        指针数组6 O) g) {. l: y, i5 a" O% Y

5 N$ I" [2 a' n详情参考:
7 Q$ `8 s' W5 J' _. g- w/ q# o: \7 S' f+ [3 l
  • Matlab参考-MEX库
  • MATLAB中mexFunction函数的接口规范(转载)
  • Matlab与C语言程序的应用编程接口
  • matlab和C/C++混合编程–Mex
      b- P4 w1 |, ]) L
% T: t# n* L1 r. U/ ]6 K# z

8 {6 r; E/ t) ^编译多个c/cpp文件! j7 l# O1 G, h
假设A.c调用B.c,B.c调用C.c + e: f, ^- @. }0 z! K
可以使用如下命令编译:; Z9 ~& S- Q" `  N
6 X: d3 X# x: q( w
mex C.c
* `. Q  e. U- ?# _mex B.c
2 ^2 C6 m5 ?3 p" C1 W2 dmex A.c4 l/ I  K% z2 ]. X* G: Z: P: }

- L: j2 {: E. _" @- \5 n2 O3 q或者
# ~% H' x+ E+ g0 k+ p) I$ O
$ x) {. z" t+ A2 E( ^mex A.c B.c C.c
& ^" p5 ~! K; j- e$ b3 J0 Q5 }5 Y
7 U# b% r2 o1 ^
4 `7 }8 p( p% i. n

! C6 h( C! E6 ?7 [) U) w5 W( c/ }- [5 F- W, m
- V, W; c4 W4 K, R4 z3 F6 t

该用户从未签到

2#
发表于 2020-5-7 13:31 | 只看该作者
先收藏了吧
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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