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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
说明/ b4 n' c* `4 x0 W0 P9 l6 D
Matlab混合编程. {2 ^5 u6 e# _8 m+ Y
       下载与安装编译器
% }, {, x! G  M5 ?. R              Microsoft Windows SDK 71CC
! B" ]" l' d+ l! I* I              TDM-GCCgccg
3 ]$ A/ R' q8 H/ l9 p0 [                     For Matlab 2015' w# W( V! n" M: Z5 e
                     For Matlab 2014" A* A2 k! l$ O+ _) B
              选择编译器
9 T6 E2 v2 l& W; ~; P4 s2 P6 m              编写ccpp文件
9 D+ x2 s/ @- y$ s7 l                     mexFunction函数介绍) ^9 W* {: w/ J1 B% x
              编译多个ccpp文件
1 a5 n6 a* b( {2 y/ Y, }7 ]8 x4 x9 Y0 _

: p5 N" W6 U+ ^/ G! A2 m+ T: f说明' x& M, t7 L  U' p4 ^
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。4 E$ W0 U1 E3 t% M

' z+ E5 i: k* c1 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)7 n/ v" b& e8 ]1 V8 \4 `

2 U7 Q3 }. w1 b, B& g6 d( S! ?4 H9 f. L0 p8 O
) \# Q0 N9 j8 U1 M8 S0 X
Matlab混合编程% E8 b! T% D( v: Y2 w9 i1 d$ p
下载与安装编译器* G; {2 F' Z! ^+ C0 t6 o
Microsoft Windows SDK 7.1(C/C++)0 E" y3 j( a' I) {
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。0 D8 f5 K! u2 U2 M7 L/ F5 D
% l6 p4 p0 R1 C* K& ?& i9 J* C
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。3 t- h% ?, @' A- z) l
, l5 a0 E& i! u7 ~9 d
TDM-GCC(gcc/g++)
: t9 x$ E* {" _7 w2 RFor Matlab 2015
8 j9 Y( j. ]+ w. P( VMatlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。, J' i) R1 [% u7 Q. G0 Z# N& m

2 ~4 f, K0 I/ P
  • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:& D7 y" i$ E& L

! O+ f- S! r% r4 h+ p% R- y 3 z, \  k& D2 v

3 [! B( R7 o4 n1 X3 h
  • 然后,还需注意的是安装路径不能有空格;
  • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
  • 重启系统和MATLAB后,输入mex -setup显示:
    4 s9 O( {6 s7 |4 M" |
9 X0 e. s+ i8 q/ k( v0 m
( Q: E. c5 L5 e+ Q

1 o6 s2 ^# |  V) o. `! \  h, k% E至此完成!
- D! h3 z# Z! c7 H! ?" w* p
6 @) _$ _+ x; @0 vFor Matlab 20149 t5 N4 x3 p+ I! L6 W
如下文章针对于MATLAB 2014a。, Z4 Q: p3 d8 ?, E. P3 \4 y0 f

: p, r% q! i7 C+ H# V点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
2 F1 v$ j$ y1 ?* ]6 _" J' w) s" ?' I( z" J5 h
根据以前使用经验,安装路径最好不要有空格中文。* @% U& r+ J" g! @. S) ~- v
5 _6 l( D% J4 A/ A6 m" g7 f
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
* U2 z/ s: @0 S" c' l . V/ l) T# A) u5 ^
* O* t$ D# n# W3 W# l$ N" i
最后的战斗:
& P+ K4 A5 ~6 o1 F$ P& I& F8 z8 s3 }因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:1 M7 |4 |& O) V) c
2 o8 I0 c( W% L9 ~: ?
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
5 B& B0 J/ n  t/ J) F( H5 `( y) s
) I& y! b  W5 X, A在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):, m+ Y; ^; C0 I. l' T$ H

6 m0 U+ f( h0 G  Q# ~/ U8 l9 d%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
5 f# C+ g: y1 w. E$ \7 F
* X- S% l/ X9 s) L下面是代码:' {2 }! S4 H( }9 }" h7 x

& B1 `0 [5 E' g8 c; X@Echo off
: ^6 m4 X- K9 [  N
; d% r9 f6 \3 F7 s0 K( u:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
0 z! {2 L' r9 v4 t. t! E% _* v::       parses it and only understands a very reduced set of commands:
" U% m5 f1 }/ J0 H* z$ Q9 F::       "set" and "rem" apparently, everything else is ignored (behaves as
1 Z, b3 c# e! x9 I::       "rem"), so don't do any fancy batch stuff in here. There are some
1 r& E  o  P5 ?8 K6 C" R# A+ n::       undocumented special vars you can set here that will trigger MEX
- `. m7 o0 x' M2 F* S4 a9 Z::       to do fancy stuff.9 x8 x7 Z+ C$ n) x9 @0 \2 W
; `& u4 m& B4 ~
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:! }" e/ B5 t9 ~
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
8 c+ D9 a6 p( H' }( Z9 L- n# Z1 d' |, ^$ Y- J! |' I2 t% y
:: Tested with the following:- c0 D4 p2 u7 O! h1 I! M
:: 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 P$ E6 w5 N) }. Y
2 m# ~' ]2 l# s, D7 r
:: Set this to your Mingw64 top folder, where you extracted the above
4 `  I, V! T! `set MINGWPATH=p:\mingw64
4 s. a6 r' s% c* l4 ^* C0 B
! h& ^6 W+ z& ?' ^:: Leave these alone unless you know what you're doing.
+ l: {" {" ?- x  D4 H: v7 b3 ?set PATH=%MINGWPATH%\bin;%PATH%
, _" _+ \. E, u7 bset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
# Y: I( ~' ]* M. w% \1 ^- s+ y' e
:: You can have MEX run some commands before calling the linker.1 ]6 U1 f  N2 t0 r& Q6 r
:: The two examples below will cause gcc to output the full path to some4 s& p8 J& E. i$ U  F
:: static libraries so you can link statically to them (see the- B. o$ [, F2 \9 U/ m$ \1 y
:: LINGFLAGSPOST special var below). You can set any command here, however.* c- [7 V4 c, c" |6 g, R. H1 S
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
1 u- Y) N5 F4 F5 @) ?  Z: Jrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
6 N1 M! v+ x) I; f$ g+ Frem set PRELINK_CMDS3=...
4 X: \$ p9 ?0 ]' _
1 P! j4 E+ ^% |) n:: You can have MEX run some commands also after calling the linker
7 v/ Z- l3 t, B:: (e.g. upx compress the output .mex)
8 G) u7 ?, i( A; Drem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"% [! B* p8 a7 n2 \1 ?. j' o$ P0 j7 T
rem set POSTLINK_CMDS2=...
$ u6 E) p$ P$ r  g8 p' @0 j5 x% _5 o
:: You can change these if you really need to.
* v5 b1 R* Z  i6 zset COMPILER=g++: p% H3 n6 C& Z9 O# G2 s' f, J
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
# `, ^, Z1 D- [( ~set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
. k" O. n# {& N4 a2 `" Gset DEBUGFLAGS=-g( g/ f" K" F/ u. y
set NAME_OBJECT=-o
( g4 {# r- D0 A, ?8 q8 c: p6 X% K+ K, f2 R* Q0 R# K3 d8 Q' e
set LINKER=g++: [6 h6 P* g- x, ^; e
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas) [9 K, X/ M2 ^) H3 c: `6 a
5 S: g8 z9 W/ @; J' u
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs5 B3 H: D: e" X
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"% ]3 t; O; i7 H+ o
3 L2 d! p+ M9 U* F9 X
( u  ~. W+ I# _' {9 N3 b
:: EXAMPLES
+ F/ }1 R, D2 z' @# M1 p5 l6 D:: ========
2 U$ I& K5 t/ Q0 m- _& i, u/ p% }9 z# V
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use0 r5 }# ?  Z# M# [
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
2 G! }+ {( A. l# Z* P5 T) j, }- Y1 u' `2 Y; [0 ~
:: To add include dirs, lib dirs, or compile/link flags, do:- z/ p$ g" Q) e
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp/ E2 [  M& S4 D, n0 J
- r5 I" I# V$ I9 H9 R

) m6 D  N$ f: b5 b% I选择编译器  d' v  u3 z. D- c; Y$ e& D2 f: u
  • 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    / {5 O6 e9 d+ Q- w2 b5 \
  • 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    9 ]6 S  y9 W8 c
  • 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下:
    $ ?4 i, F0 G1 `# G 4 J# G, s7 l" c( n) O& g

& P7 Y4 a/ ?0 }! I  \2 d3 n' \  k: P$ g
刚开始我也以为不能用,后来试着编译了一下,竟然可以!
$ j0 H+ v3 x2 K! S: w# D       / {0 m3 q, r; T1 ^% N) n% L
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
! d; z; x" L7 G" a9 x# P$ t7 `! _1 u/ e( f0 {3 }9 X7 @

9 t: j7 m4 M1 J编写c/cpp文件
1 b0 `; j5 ~5 i0 V* F6 @/ Q与普通的C文件的编写有两点不同:/ k  b& I! U5 f4 E" p& z( M

: X+ f( x* [5 a" P: Y
  • 包含mex.h头文件,即:#include "mex.h";
  • 编写mexFunction函数。" z' t( ]7 s) g0 e( k
6 z/ P. l8 ~0 X% s0 b9 {
/ q0 F  O' ^4 D* [
下面以一个求和的例子说明:1 {$ H) C. U. @+ ^5 P, C* T
  ~# a( e. N7 s" f2 [
#include "mex.h" // 使用MEX文件必须包含的头文件! i) n) L/ W- t6 c* T5 K- {
// 执行具体工作的C函数6 E2 w8 ~- @/ i/ `0 ~9 M2 Q
double add(double x, double y)
% |8 n6 x  K* Y! }- B{. g2 _7 {! n/ a* n, P
    return x + y;  W9 N+ Z" ]0 i( _: I+ U6 k3 o
}
, W% ]( ^( `  ]2 l7 Q; V- \4 c5 B// MEX文件接口函数
, m. H/ ^  {5 H9 \void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
2 z1 G1 u1 c! ~7 a+ I- S8 `4 j{
" V- E9 s: s+ W5 O    double *z;- u. E+ t. y- s* Z$ F
    double x, y;
' N& j* y! f: B% H* G5 m) R  o1 `    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);& @* P  @7 g' A3 J3 ^9 g1 N
    z = mxGetPr(plhs[0]);
0 Y) D, |7 w% ^$ G9 M, ?! z    x = *(mxGetPr(prhs[0]));6 ^/ |  N& W: V
    y = *(mxGetPr(prhs[1]));
0 J  M( M) b- O0 M1 T3 P0 [    *z = add(x, y);6 N  o) P9 @0 z/ w# Y" Z! F
}* z$ S! Q6 W/ ?1 L

6 A6 X' w: g5 ~5 C
( v) D1 k4 e1 g! L0 V+ o+ I( r+ Z7 WMatlab命令窗口输入mex add.cpp,运行结果如下图:
1 w6 f6 M& T/ S9 r
0 h2 Q* G6 k% n  W$ V3 t8 y# e  k7 s4 O: h; V( c( |& X
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。$ A* R1 V$ T9 |8 w) z

/ e; t  ]7 q7 g: l- V) umexFunction函数介绍
3 |2 P. o3 e1 F+ H' Z- NmexFunction函数接口如下:
, J# b; X, z5 L! A0 B
; S' H4 }. ^9 T, t# \! K' Yvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
' I1 [5 L2 d% {$ p5 e, t  K: V8 }3 A$ z4 z0 N
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:/ y% Q2 F' _+ N8 u% _. X: Q
  f" w) ?0 M% g7 `; |0 H
参数                  意义                          英文全称                 类型1 ^& O* R% R. u& I2 M6 l6 [0 u
nlhs        左边输出参数的数目        number of left-hand side        整型(int). a( U7 n& j8 A$ {' e) w+ o; w4 d
plhs        指向输出参数的指针        pointer of left-hand side        指针数组
% q7 o/ Q% x  G' c" [nrhs        右边输入参数的数目        number of right-hand side        整型(int)/ h+ U) l+ K/ n8 F' c
prhs        指向输入参数的指针        pointer of right-hand side        指针数组1 i5 X, P3 ]! s* P- H
4 Y+ I; Y1 ~. h7 K. R" ]+ Y
详情参考:
! Q/ Q0 Y- ~7 [! z, @) L7 b8 f3 \& p" R5 V2 w! p! P  ^5 Y
  • Matlab参考-MEX库
  • MATLAB中mexFunction函数的接口规范(转载)
  • Matlab与C语言程序的应用编程接口
  • matlab和C/C++混合编程–Mex
    % `+ u( r6 H4 N" S
8 l) \0 F) b2 ?$ K5 A* o& t: z

6 x0 m( v- e4 A7 P+ }$ {4 N编译多个c/cpp文件
8 y0 N3 x/ k: x2 t" f假设A.c调用B.c,B.c调用C.c
) c: N8 ?, n% L可以使用如下命令编译:9 n4 Y+ y9 r- s: a

6 p* o- V7 I: z' G9 M, Y( i& J2 F4 Kmex C.c
, S1 j7 X% A& q! e  {% l# S1 Kmex B.c
- {' t$ C4 k* w3 y0 g0 mmex A.c9 G4 n* D9 r- r' c6 H, w8 K" t" O
8 O1 Y3 F' @/ V1 f' A
或者3 a6 @1 S7 K2 V, A" k
# s$ y* `* j: V
mex A.c B.c C.c
: W& I5 h* ]5 Q4 V
6 @' Y- {5 z+ c3 K" n" G$ b8 U3 _3 t6 `
- f, q$ O+ _$ T$ o0 |" N
" M1 ^6 z" n0 S$ R! t" a) f

8 ?5 R( @  J  @4 B7 W! }5 F. G
% D/ ?( S" t7 |

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-24 10:57 , Processed in 0.171875 second(s), 28 queries , Gzip On.

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

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

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