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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
说明( b0 v4 T+ E9 M' H- p: d& Z
Matlab混合编程! m/ J% V* N. C9 v
       下载与安装编译器( q3 `# u+ Z4 F9 \+ A) L/ S
              Microsoft Windows SDK 71CC
0 j: H" Z4 m" p" d  f3 D! K+ j+ J  P              TDM-GCCgccg
, A5 v! _% f1 m/ Y                     For Matlab 2015
1 S: H# S2 \" e* ]2 b5 U3 K                     For Matlab 2014/ `* f3 u' x' R" [. z1 R
              选择编译器4 h# F# A- @2 X# ^: x8 a- V
              编写ccpp文件$ p' G2 y6 B+ E+ ]' H
                     mexFunction函数介绍
, A$ j/ K+ @8 S9 Q4 f) h              编译多个ccpp文件
5 V8 A' J1 S7 ~, P' X9 `' J8 m7 Q% ]

" k: f: U2 O% x' b6 h: i- T. A说明* B+ w/ @6 O8 i, x5 S5 Q
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。4 k$ K  E0 l- _: I: c

3 v) v* i4 g, {
  • 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)
      X& U- i  A8 M( g2 Y

3 ]# _% F9 `' D8 M
$ t% d# R+ Y; [$ Z- U8 ]; [$ s) q+ e
Matlab混合编程  Q9 d- M  |+ k" m9 f
下载与安装编译器
/ ~- l0 x) ?9 H; D& T; OMicrosoft Windows SDK 7.1(C/C++). [6 X" G8 X, B4 w" I5 V' R
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。: |8 Q0 z4 Z. y. {- {4 A

4 T9 f0 z: i6 T" `- B下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。. M) L7 u  q8 V, U* p& ~, o/ x5 E2 H

8 [3 `) U& @# P: |# i9 qTDM-GCC(gcc/g++)
4 b' [" j! `" U" a) \' ^. TFor Matlab 2015
; F$ R# z  v3 iMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
8 @! t0 H: v. c8 n5 q7 z( W$ m+ M/ Y
  • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
    & }, i, T7 C& I- O

* M& ~: T- ]7 }   d! E  m' u+ u
. s1 v" V7 E) g% {
  • 然后,还需注意的是安装路径不能有空格;
  • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
  • 重启系统和MATLAB后,输入mex -setup显示:
    7 E2 v9 w) G" F6 g* P

/ a2 q+ Y/ m& d+ P5 a
, x- [6 [, {7 V- Y
* o9 k$ ]4 Y; f1 K' j至此完成!
- ^2 `0 v* t* q
  j" }- |7 B: z) u6 `For Matlab 2014
, a& _) d- i; Y6 n) z4 Q0 h! }如下文章针对于MATLAB 2014a。! w/ Z# Y8 _: ]: [, ^! g! W
1 f' Y4 {6 ?7 J1 M7 R: F+ N
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。' m3 w7 F+ P  f: S8 X% ~2 O: V

9 ]) r+ T& Y: _: P根据以前使用经验,安装路径最好不要有空格中文。' j  C  w$ G* v$ Q( \

* E; H3 }0 [5 u8 _安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
1 w7 B7 x! W: e4 g/ \* K1 B8 [ 7 e- [( h5 t2 n1 R  S2 ^

. ?; o) X& f4 o3 a$ b9 Q/ U最后的战斗: 3 e* a* V8 p7 k* C4 T8 g- r# q
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:
) h0 y% l2 S) T+ R8 }% }" i
4 o3 H" z. }! f9 q" c下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。4 V* T) `! B9 M
' y1 v0 [5 d3 U# z" C! m" R
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
2 N6 c0 A3 V% }6 r0 c& d" T. k8 p/ N! |% }; q$ }
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
# |8 L* w! h8 q4 w, J
6 m- u; _7 i" j! D; S3 p2 G1 S下面是代码:9 n  o6 P* u7 P" ^

7 t, n" m. }4 {1 N. c8 w1 R@Echo off- @. X, x5 }" [5 r2 d
! G8 Q4 E5 p& u! E- b1 m
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
% n$ N  O8 Y# k) p5 Q- N- L::       parses it and only understands a very reduced set of commands:
. r( v% D$ Z2 Y" X  W; N0 Y::       "set" and "rem" apparently, everything else is ignored (behaves as
/ V1 n% [+ k4 z" K::       "rem"), so don't do any fancy batch stuff in here. There are some
( r, l' q8 B" s2 L9 \5 I; }) `::       undocumented special vars you can set here that will trigger MEX
. K8 b+ h: }' v* \/ Y3 i" r7 m::       to do fancy stuff.+ f3 H+ @" f" M+ R' ^# @& A
, `4 }3 n2 Q2 B5 E' F
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
, j0 R+ f2 U# u5 J) n- Q:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/' _+ x- m# ^  h, H% p
! o+ n/ ?8 `& g
:: Tested with the following:8 \% G' M% P; F& ?! T6 k
:: 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
/ ]1 ?+ ?+ f2 l7 Y' j4 Z- g/ _, ], ~2 ]; o0 h3 u- o
:: Set this to your Mingw64 top folder, where you extracted the above2 A- y* l8 d4 w% Z2 o( m0 W. P
set MINGWPATH=p:\mingw64/ r0 d5 j6 X5 ^. {7 z2 @* v  k$ w3 p$ M
( x& \0 \! t, [5 C9 I  ]4 b
:: Leave these alone unless you know what you're doing.3 L" R$ X$ N" G( a3 m% B4 @: b
set PATH=%MINGWPATH%\bin;%PATH%
; l9 a& |+ }6 v. Z& V* S& C8 Tset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs0 N  n. P) B* G

3 @. p5 y3 `$ u+ X& U:: You can have MEX run some commands before calling the linker.
4 i" W& v! ?# J& e3 E1 I:: The two examples below will cause gcc to output the full path to some
( P6 q; |# D2 c8 s/ e; m+ S  h:: static libraries so you can link statically to them (see the, F9 X. l# G* f' ^
:: LINGFLAGSPOST special var below). You can set any command here, however.; w* K; z' I1 M$ ~3 G$ d$ q
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
/ D2 ^& z9 W" l6 R& wrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs, X' N. |; J5 }; X& Y+ O% @% X
rem set PRELINK_CMDS3=...
" U2 D0 g8 {7 }* v- s: V
& r: s0 O' Q. X: `, m:: You can have MEX run some commands also after calling the linker
+ R6 |% F; r( {- e9 S:: (e.g. upx compress the output .mex)
' J6 y8 K' g( U2 Lrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
# g& q2 l. Q  H# ^- Q, {rem set POSTLINK_CMDS2=...4 p( m( \4 }4 g$ @. l- U
& n# p* w4 W( T. p% m
:: You can change these if you really need to., c/ ]/ J' k: e3 ~9 ~
set COMPILER=g++
' m  m' ?5 U/ D; Y2 D1 w6 aset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
( s8 ?1 _/ y7 n7 E9 X/ m* Yset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG% A: q( F  K. t- x1 M% I; L8 y
set DEBUGFLAGS=-g8 f( @( j$ I3 s6 ~
set NAME_OBJECT=-o) W2 p2 V! |* t  v2 `
3 X6 S" k' j* x9 d* z* E7 K5 c
set LINKER=g++% G, M- N) z' s. B
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
4 t8 H- k) e6 `5 P: ~3 f" Z' A
3 d9 g( k1 C" \; u8 cset LINKFLAGSPOST=@%TEMP%\mexstaticlibs' o1 D9 M+ U% z
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
& y' ^3 k4 d$ e* e0 \
; {1 }; C8 _+ \0 R& _1 Q6 s; c
8 b: d$ B& I$ J$ M" k9 ^; y:: EXAMPLES' q3 z7 _% Q+ ?- {' {0 ^! K8 }
:: ========1 V! a0 g# r! D' @1 t4 I8 w
0 Y% m9 M& Q2 {* H2 i* v" P( A
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use( s0 [8 }# ~$ S/ B
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing." [( Q* T8 u' m8 \/ P0 d/ A- E
/ y5 r3 e) s6 F6 V! P
:: To add include dirs, lib dirs, or compile/link flags, do:
+ A; ]& R" u' ~) ?:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
) x3 r3 B* \& N( w& F0 _; J* H1 f3 @. B" s$ K
2 ^9 v: F, w" t' l% \# z% G3 r
选择编译器
1 d3 ~" Z: ?* ^
  • 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:3 x0 O# n" V2 V$ M' W! [! v. \
  • 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: 2 c0 u; d* F' S9 i# {
  • 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
    1 G- {" u. E. n/ L7 |
    3 z' |5 [2 R7 r6 U* h+ ~- A' {
- [' n2 k5 D' g: t9 _" D$ ~

+ b# V. n" @- o: O! g刚开始我也以为不能用,后来试着编译了一下,竟然可以!
3 Z1 h6 f' |; R( Z3 _& h8 c6 g: l2 |      
8 i2 I& J# z; S4 o$ Z% {DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!; H; j% i/ Y& e% c( W! F' w

& X6 c2 q) c  g' O) u; [8 f8 q* Y+ _7 C4 T
编写c/cpp文件6 I8 E, I) g' s
与普通的C文件的编写有两点不同:8 q0 S/ [9 ^8 I( M; @- c( V

; ?( U$ ?1 O. O# x3 l) w5 M7 f
  • 包含mex.h头文件,即:#include "mex.h";
  • 编写mexFunction函数。# X$ h2 [: z" E+ i6 `1 m. B
' e% b' b0 `; \. X; Y! ^

/ y6 O. }5 y7 y; x2 T. ^9 H下面以一个求和的例子说明:) p9 F9 G* w$ L
% F! B: n6 e' \6 P
#include "mex.h" // 使用MEX文件必须包含的头文件' ?- ^  b% _1 J) ?, A
// 执行具体工作的C函数, J3 p  P4 ^9 `/ N. I( x
double add(double x, double y)
0 j9 S( e9 n$ x" ~$ W{& O9 }$ u8 J" i$ O
    return x + y;
8 b7 C" T1 v% g, t) g! u}8 f8 l. H1 w4 k$ ]5 Y# T
// MEX文件接口函数
8 G* q( Y0 a8 N, e1 vvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[]), E2 L7 p2 s  k7 J
{. u' r0 X( O- W7 q8 P* R( }1 e; P- l
    double *z;0 A7 q6 C# i$ i/ k7 h1 |
    double x, y;4 h* X; \  ^2 k7 R+ o
    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);4 N/ b+ P% t( t: C5 D0 ^
    z = mxGetPr(plhs[0]);; Y' t. n7 @& ]
    x = *(mxGetPr(prhs[0]));3 Y6 m+ {. V( x: k* M
    y = *(mxGetPr(prhs[1]));
* c6 v  L- s) c( U- K5 n! d    *z = add(x, y);
- l9 E( L: [4 @) a+ p}
7 i# o, n* ?+ w! l
' B- Z1 ^# p: d: C
6 W/ R- ]) \! b- k/ V( ~Matlab命令窗口输入mex add.cpp,运行结果如下图:
8 m/ ?) q1 c) U # C5 y* E( Z9 g1 N3 N. }$ o

3 V& L; Q0 J0 a2 h* }3 u在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
* W" L# A" K7 B; ~) R, s( ?! |! g( A. z
mexFunction函数介绍
) i; a5 {8 p  m% p. m5 E: @8 LmexFunction函数接口如下:
+ `2 r, H4 X5 i- d. O. ~, Z0 K" y8 N
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
. `( `% ~2 t+ G" Q7 ]) r
3 _7 V; f. o+ S) X) {可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:- P. |# B$ H; f

$ A6 [! w/ Z1 _: W8 D7 ~9 i参数                  意义                          英文全称                 类型  D' ]3 L+ T$ K. x3 S# F  ?
nlhs        左边输出参数的数目        number of left-hand side        整型(int)* R& l; `/ B5 w. u' W  E/ ]5 _
plhs        指向输出参数的指针        pointer of left-hand side        指针数组5 R$ L' ?5 P5 N4 J; A
nrhs        右边输入参数的数目        number of right-hand side        整型(int)
8 c, G& e, ~# X' Jprhs        指向输入参数的指针        pointer of right-hand side        指针数组
8 p7 b7 N2 c9 u4 o" s7 l6 M0 G# C( U$ E) V) F/ U& p: H) [
详情参考:. N: K3 z$ y7 W2 c
8 e9 ^$ R. t) F0 I: @
  • Matlab参考-MEX库
  • MATLAB中mexFunction函数的接口规范(转载)
  • Matlab与C语言程序的应用编程接口
  • matlab和C/C++混合编程–Mex
    5 D  k6 [8 i( _( g
, P4 B8 d' N& u! s

/ _' A% o: z+ |! w编译多个c/cpp文件9 g. O( H, E* {6 r( ?" q
假设A.c调用B.c,B.c调用C.c & X+ ^3 K+ m; Q) X: L
可以使用如下命令编译:
; C; r0 ^5 M) N5 u0 h, h) r7 s$ S; H; H: k
mex C.c- ~6 F- w/ ]: v) ~
mex B.c
! Z+ \- U* ?" t) k; Umex A.c3 N) B0 N4 G: k0 }$ g$ y  z3 o

4 T' c' k! K5 z; X/ f或者
2 G( X) H2 e  [# d5 D# F" I1 M
8 f. b  o1 ]4 R6 }3 Smex A.c B.c C.c
& ^5 {! m7 L, F/ ]7 M4 ]5 e* m: M6 L: U- ?

- C+ M, Q0 o/ Q* v; j: F5 a5 }* m7 a0 h& Y) R
$ a* }5 \9 Y! `& l7 k

5 Y9 N/ |3 l9 w! w# Y/ w! e& r3 ]' R) r

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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