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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
说明
' \, f, z. i& a" G* e" dMatlab混合编程
7 f# w# W; q; b: N       下载与安装编译器
0 _- o, P) f) D- E- J              Microsoft Windows SDK 71CC1 @1 {, U. |$ n
              TDM-GCCgccg0 I" r5 N; m$ V8 i" B; ?3 K, C8 P
                     For Matlab 2015
3 v$ ?+ |# j5 N, X                     For Matlab 2014
  t" n0 c* a$ g+ R$ H              选择编译器
! D3 [: x& W' a              编写ccpp文件
0 u5 s! ~% g. h$ d6 M4 I9 t                     mexFunction函数介绍
  [# r3 M7 b! h8 |# v, j4 v6 y8 Y              编译多个ccpp文件& S; @& p3 S& x. E
& {* v$ U, a: x# e
0 q7 Y' O% s3 D" \" p: D; C
说明( e% S* e+ s1 B: q( i
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。4 g; A7 z! e1 b( W2 \  S/ T+ Y
' p7 P$ \9 T% @) e
  • 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)
    # v) g0 o/ v  n& W* n1 A; N& O1 x

& ]0 k0 i; W* t2 U3 s4 [* ]& u! L; V2 S* t
+ ^* ?8 ~- g" p, i; t; z+ C! [3 I4 z9 D; j# e
Matlab混合编程( b0 b* O$ O: G
下载与安装编译器" V$ [- B+ c' s
Microsoft Windows SDK 7.1(C/C++)( h& @+ Y4 y1 x) ~; ?" C/ c
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。4 H! x+ g0 u) O( F
8 M* Y1 s0 v* ~
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。$ i* e4 U' l5 z' Q$ R

' |$ b; F1 R/ ?5 V+ h# @" }TDM-GCC(gcc/g++)
2 V7 k1 l+ }+ u& UFor Matlab 20156 S. R; S- Q7 y4 ], }* i3 y
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。6 t) K9 r. x; ?% x' ~3 O' |
" c6 m' L! k7 |+ E
  • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
    ) e! _3 a  E; y4 m& @$ Z" p

7 C3 ^' `/ r, v+ B8 ~
+ ?- i- x6 c& R
  F/ F$ H0 ~6 v! O1 O+ X
  • 然后,还需注意的是安装路径不能有空格;
  • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
  • 重启系统和MATLAB后,输入mex -setup显示:' i+ @  D3 w  B. [* m- S- W' C- {

8 a+ e& ?1 K2 w1 D$ ~1 c9 [
7 W4 e; h4 l+ Y6 L2 d7 D! v1 A" f# f. Z* P& I+ G3 o5 X
至此完成!
- b/ ]/ X- g' a' Y8 B1 S, ~! b  L. f5 z  f5 Z
For Matlab 2014
& W+ s! T5 W  y7 C0 z如下文章针对于MATLAB 2014a。
5 e' x/ L0 k% K( w) P: D1 Q6 A* c$ J5 B- p
点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
' k# d0 F4 g/ N
* _% l" H' j) G& i0 Z1 Y0 y" Z根据以前使用经验,安装路径最好不要有空格中文。3 w3 Z+ w! K/ q

5 {' ^. Y9 n( Z; y6 V: ^安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
1 j" l5 _3 D8 F. G. u! |
+ N" p1 `8 d0 O) h" J
  t4 p* |8 @0 c3 h最后的战斗:
& _3 X. t2 A: S因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:3 b* ?8 L3 e- f% V. M
  f% D! t' Q0 A) @: N% c2 C
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
: O1 k: x4 P/ [& @+ V9 H* }- U1 B3 \
在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):* L  ]3 A, V% j# L) @
. Z2 t! v. n3 \
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\+ X8 j; u, I& w7 x. f  U

7 N; H  P" ?# P: G, a下面是代码:
1 u4 P6 p- H: Y4 T# h  H( }0 w: H5 b* y) A( ?  r  Y( z8 h
@Echo off
5 u* g1 ^$ O' \. U% b5 q4 r' [) V8 X5 n
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
1 z4 V! T1 X! F" u: \; B8 b' _::       parses it and only understands a very reduced set of commands:
6 {/ u. O0 W0 u::       "set" and "rem" apparently, everything else is ignored (behaves as
" N" f6 c& G) @9 p2 f% h::       "rem"), so don't do any fancy batch stuff in here. There are some& E) J% g" K4 P7 H( R
::       undocumented special vars you can set here that will trigger MEX" _: {8 {3 J* ~9 D
::       to do fancy stuff.
( b; x& L% d+ W7 I2 Y, D2 ^: [7 Q3 z. ^* {' z1 M' D* l
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:' v* \5 j% X! L4 z& a( L
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/2 s4 Q$ Y6 N9 s% W+ }
5 J$ i# b- L1 T# K+ ^' e
:: Tested with the following:
2 u8 ~6 h! \8 U. Z:: 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
* I. y8 J8 L  S& {4 |
; H0 A$ ?8 h. }# H" e# a+ D:: Set this to your Mingw64 top folder, where you extracted the above- o' \$ e9 R- W- ^$ G9 z4 L
set MINGWPATH=p:\mingw64
" J; |( T, I) R: ~
/ E# M* Z7 P$ u. T5 P/ O& N:: Leave these alone unless you know what you're doing.
  C6 R1 B7 c5 J7 H. F, k# bset PATH=%MINGWPATH%\bin;%PATH%" m  _3 X  g. Y0 b0 K* }
set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
" w% V: E9 M% \" ]! L
& u" y% Q# K6 W: g% w& x:: You can have MEX run some commands before calling the linker.
& h0 q- E  B- m. y  z- H/ B' v& Q:: The two examples below will cause gcc to output the full path to some
# S* a' I6 [& F- a:: static libraries so you can link statically to them (see the1 n: a9 l1 ~3 g2 L9 B' Y( ?6 O
:: LINGFLAGSPOST special var below). You can set any command here, however.
4 j; i  i. i% prem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
% f7 {* a; |7 J$ c8 Urem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs) p( d- U. ~+ F9 r+ Q' ?4 O
rem set PRELINK_CMDS3=...' E& l6 K7 L2 q3 }) g' R
/ `2 j7 D" G  l% {
:: You can have MEX run some commands also after calling the linker: @, g; q/ Z, @+ m' r
:: (e.g. upx compress the output .mex)
" r, S1 u6 ]1 S& B: ]/ L9 \rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"! M$ S% v4 R9 `  \# ~
rem set POSTLINK_CMDS2=...' y2 T" R2 v3 `/ c! P
3 L# _' m  H+ g8 x
:: You can change these if you really need to.
6 A. B% f$ o" o4 dset COMPILER=g++* E  S- w" I! o; l4 E& i6 F2 W
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE) A4 O$ G. U; P( h0 J) S
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG- N* A# Y) c+ h: @8 t
set DEBUGFLAGS=-g
7 g7 I6 l3 T) P% u% T3 F' U( }set NAME_OBJECT=-o( Y# @: m( B/ u% Y2 U0 o1 c
6 K  H3 ?6 C" {/ |8 f6 x  }, k
set LINKER=g++( v- D/ d+ t* X* W/ j& ]+ o, C
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
/ e4 a3 x9 e% w; v" y
" z2 A0 ^7 z( K& u/ P& oset LINKFLAGSPOST=@%TEMP%\mexstaticlibs4 H" }" M; n1 d( f0 _
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"1 i! G- [4 V8 C5 X6 y
7 z! k7 n+ B& L- v
6 a  C( T) M. [7 N
:: EXAMPLES
, t4 `" w' E. i:: ========
& u; S; [; [& H8 F( l1 f* @4 `, Z' N9 b
" g% m: u( \7 Q:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
; w' E1 k9 ^+ Q0 n:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.. |' O+ B& E$ C$ B7 M8 q- E
% C, n5 X5 J- c1 ]
:: To add include dirs, lib dirs, or compile/link flags, do:, E/ b' \1 e- l! N! n" {$ V
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
+ o2 _  o, C* h2 A1 V# m5 Z
# u, ]/ l2 t+ F+ Q4 r
3 C& b; r$ ^+ h: ]( `1 n选择编译器
' @+ d6 j2 W* ]$ [; ]6 }7 F, h) T( k
  • 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:; r0 g4 ~, D3 b# ]& a
  • 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    9 I' F) U" Q" b1 K3 o3 H
  • 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
    # Q/ @4 C  x! X% k" M# ]; l+ Q
    , z1 H! {3 j* U* Z( C" n* \

- ?  Z; u+ l) W& g0 P+ j
/ t  R8 N, E! O$ V$ p3 ~% ~: i5 }刚开始我也以为不能用,后来试着编译了一下,竟然可以! . S; K) U1 H2 D  R0 ]
      
- T8 W* j- f5 z+ uDT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
. P, P% s6 y; I
5 V% ^/ J  H+ a3 _% ~  H3 V$ k1 F
, M& `! Y, a- v编写c/cpp文件
0 Z2 q8 S0 B, a, Q) j5 m( s; [与普通的C文件的编写有两点不同:
- ?* X5 v# s$ }. T1 [/ n
2 V0 S8 B: u+ u0 P+ Y. D
  • 包含mex.h头文件,即:#include "mex.h";
  • 编写mexFunction函数。6 [+ L# j% g  O( c9 t3 x7 S
! X4 ~3 @7 U" x- r

; x; H2 W7 ^# r0 ]2 T& Q% ?- c* y下面以一个求和的例子说明:2 \, Y: K8 Z5 M- G! B' u" D
+ W# @( A8 O0 v' S5 L0 c
#include "mex.h" // 使用MEX文件必须包含的头文件4 D  u! }4 q8 q
// 执行具体工作的C函数, `0 M5 r; X4 M* l, l( R
double add(double x, double y)
6 k! S; A9 l5 o- b5 H; R{
# }6 C( D' N% k, M    return x + y;
) q  ~# Y% |* {8 ]: [}' P$ F% J) C3 `# y0 y0 z
// MEX文件接口函数  e! @# A1 @- b+ }
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
- O9 b4 b4 S/ v7 {{
! k+ }1 M& S' Z. @4 ?, `  ]! r% D    double *z;) ^( ~3 u. y: N# {9 H
    double x, y;
, g& J2 G, B& i( n: z    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);4 h3 ~9 y2 b* o! J3 j. P/ ^: \( \3 ?
    z = mxGetPr(plhs[0]);$ G# E8 o+ H; u" X+ c
    x = *(mxGetPr(prhs[0]));
8 y9 ~7 p8 [; d" p9 }/ U' e6 ?    y = *(mxGetPr(prhs[1]));
4 d' J$ }7 ~# r    *z = add(x, y);
, l! D$ O1 I1 D' E5 t}
  E: U0 [. r  q& U3 O6 r+ M8 [9 o: w; e* q) `6 w- t
6 w5 L4 T7 P4 K* b8 M8 T4 Y5 Q
Matlab命令窗口输入mex add.cpp,运行结果如下图:
( s% M2 P$ Q4 k- u( F 2 k, K6 Z. `) }# ]( i$ o
; i- s2 j0 _. m- z9 S9 W7 P1 ]: J
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
( k) T; [, O9 e3 P  v+ S
7 P1 P  j0 u0 G4 hmexFunction函数介绍5 P; X% X, u2 B( d4 S' m9 I
mexFunction函数接口如下:
6 N' L$ v. p; a! |. m3 u* f& L$ j$ W! b5 B# u4 ^% X  |
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[]): K. L1 M) |2 {  s  a6 T5 i9 ]
" g. j; F5 Z, S
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:- s6 Q) E% S% e* D# d0 s% K/ q) Y

; P- @  C" H/ B4 ^, S  a参数                  意义                          英文全称                 类型
, `5 |' i9 n# O" C3 fnlhs        左边输出参数的数目        number of left-hand side        整型(int)
3 r$ M3 I0 S7 Z9 Q2 Z$ lplhs        指向输出参数的指针        pointer of left-hand side        指针数组2 X! B. r1 F4 M! T6 _
nrhs        右边输入参数的数目        number of right-hand side        整型(int)- q! l: B2 \0 |, l! b1 X" G) I% x
prhs        指向输入参数的指针        pointer of right-hand side        指针数组
4 L: C* Z0 e- T4 E
6 c- n. t, _1 n4 L. v( ]详情参考:( G0 U$ Z* W3 d/ l

) P; `$ N: d: y5 ?( z5 l9 P
  • Matlab参考-MEX库
  • MATLAB中mexFunction函数的接口规范(转载)
  • Matlab与C语言程序的应用编程接口
  • matlab和C/C++混合编程–Mex
    8 |1 A& n+ }1 g: [0 B* R  a
9 \% N5 `1 s8 ^
: {; F  h& {- N2 B8 h
编译多个c/cpp文件
) r& G4 @2 U4 c/ P4 l$ o假设A.c调用B.c,B.c调用C.c % ~& w0 Q! |% p: t: i3 l
可以使用如下命令编译:" ^5 |! }2 j, F

) v' s, O& Y& z) ?mex C.c
$ D, C, v1 Q' zmex B.c
) P9 n  H! J6 m" Z% ^1 K! X% xmex A.c
& W  \: z( A) N$ a' X6 k9 l: y$ |6 [1 J6 }6 X% ~/ g
或者
# O( D* |" ]0 ^9 {9 e$ R( S$ v/ g$ g( W7 X" A
mex A.c B.c C.c6 ~# K; ~$ O; q& w& @/ I, s

4 f8 |) {( A* A5 b$ x8 K0 c2 f- u) l
  B6 u6 |" n& {

& ^! R  i" V; G- x
* y/ K3 H0 {2 H/ X7 J! u5 i. g# ?& p+ R

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

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

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

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

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