|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
说明
# i i8 w+ n7 w5 p5 k0 I- j: zMatlab混合编程
$ B5 z0 r `2 M; n8 P2 u 下载与安装编译器
) S. ~9 {4 v& b5 O1 ?% p Microsoft Windows SDK 71CC( }1 ^7 h$ A7 N" j- z* T# r
TDM-GCCgccg
$ [# b9 t) o0 h For Matlab 2015" D8 f" \* F: R
For Matlab 2014/ C+ W a- y" |5 P: Z4 o
选择编译器, x8 b% m8 b3 ^$ d& y8 O/ Z9 b, m
编写ccpp文件% r+ D0 a4 `4 u: U. g
mexFunction函数介绍, E5 Y6 g! V$ W
编译多个ccpp文件3 l- y% L) _" {, Y2 \# T( ^
; y6 V+ k) w! n* H$ @/ |1 A
9 n, K( n. p& m1 t2 U% w
说明
& m8 T6 i- @* B4 c$ |& m( S记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
5 D8 {- x" K& F- S+ R5 y( m
( M. n% [3 B7 \% z8 j. f: K& a0 V3 U- 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)
/ i. I! _- r0 h# p& l3 i/ S3 \ : \+ D3 E' V* l: D# s* e% D2 H7 f
( h% Y: }7 _, o. \( N! f2 O
" s% {0 C' }7 S1 f
Matlab混合编程! G: K& s( a' s" I- j; ?4 p0 W- t
下载与安装编译器
" c+ Y/ W M; Q: O6 P9 f1 X0 q8 \Microsoft Windows SDK 7.1(C/C++)) j) _% s; @6 u% I2 v! `
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
. j ]* r: U2 W* |0 W; T4 r8 T# _4 |; i V* J
下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
* r- j4 K+ x. s( Z& \
$ _+ I# r. [5 x# h8 Y2 i# r. JTDM-GCC(gcc/g++)
/ e# h9 H t- J" [For Matlab 2015! j( @" b! h5 D* d; }, g8 y
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
5 T& g0 T, N0 j( p3 N
+ i; x- T* }" l1 ?6 E- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:) l' r" z9 }0 I
1 I5 Z: _) L; Y, n9 t& n6 a( @
9 a; ~9 z0 D; H( t/ u
7 y- X3 D% `3 y0 Z- 然后,还需注意的是安装路径不能有空格;
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:
" B+ s" L0 N- M1 u $ b5 p, h, V6 z/ z5 }
& I7 C; Y# a$ k, I" U3 @! O4 g
+ I( t$ ^5 L, e h8 H6 E至此完成!- l0 Z: g2 o: B1 z' L
6 S( O5 e3 X( x1 Z9 T" ~For Matlab 20146 D( E" z/ ^4 }; _# K1 t& A+ Z, e6 w
如下文章针对于MATLAB 2014a。/ W9 N+ e1 z/ h
8 X8 `6 d- d& Q8 G3 Z9 i) P: E) }点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
4 Z$ v+ U; _/ j: M% i# U! H4 d
% X4 h: D$ ^& w p4 F, ]0 d根据以前使用经验,安装路径最好不要有空格中文。% e/ N/ L+ I0 h9 \% W
' }( N+ M d8 j! O. X安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: $ ~, E k8 H' ~% M# u
* _7 W" P+ s; O7 b. _% V2 s) A& q8 c' ~
最后的战斗:
# p; o; N, |1 j6 g- Z8 _8 Z7 K因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:6 a* K, U5 [5 x2 J- | |; f2 }
' ^* {0 |$ u; [
下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
3 q0 G2 I/ I: D+ G( X
6 i6 s0 d1 c, V8 b8 u在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):) R1 m1 v! [0 I# g& c% `
; v3 Q. j. s$ h
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\, N) D2 p0 h! p
: z( A2 W8 P, Z下面是代码:6 G/ H( T+ a0 Z2 p
) z& t4 ]% K2 p. N3 H8 S
@Echo off
% U- A# V5 r) W C
9 p: T1 }* W. T. E9 R2 Y5 M:: NOTE: this is actually not a proper .bat file executed by Windows. MEX; Y9 @- m2 O* Y4 U
:: parses it and only understands a very reduced set of commands:
w( I; x* A! f3 L9 d:: "set" and "rem" apparently, everything else is ignored (behaves as
5 E0 U @8 _0 x) z( Y# P, O0 k:: "rem"), so don't do any fancy batch stuff in here. There are some
% a8 @4 F% _! Y; W9 H' J) |:: undocumented special vars you can set here that will trigger MEX. L2 C' R3 B( B# s6 `$ ^
:: to do fancy stuff.
, @* E1 j; k# X/ g
- ]9 Z) v; D6 t! l& r% [8 s9 ^:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:' Z- N' a' Z: {0 h# s
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
$ C7 s( j& e3 H3 h( L% g6 B4 j7 i4 t. t8 i, l' _
:: Tested with the following:9 R) K% a# o6 K% l
:: 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$ N _! a- n; u+ B: m# w
3 z4 }! ~ x; X* o/ e( n:: Set this to your Mingw64 top folder, where you extracted the above6 h! W ?% m+ E- R! d
set MINGWPATH=p:\mingw64, h G- r7 Q. y; c. A1 C' G5 F
: Y3 m( i) U8 E5 [
:: Leave these alone unless you know what you're doing.0 E, N. Q/ r- W
set PATH=%MINGWPATH%\bin;%PATH%
/ n1 |! X* ^& K: hset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
# t( B3 H, h8 h- _
& C: ?3 s% |) [, Z; y. m:: You can have MEX run some commands before calling the linker.
0 |' J$ K# N. P8 V3 ]# `9 Z:: The two examples below will cause gcc to output the full path to some. {. ]5 k- P, x) _- X. `$ e
:: static libraries so you can link statically to them (see the
% ~: |) A" s+ O# l# w+ p:: LINGFLAGSPOST special var below). You can set any command here, however.
1 a: [, u6 ]! t* c5 S# e+ z- vrem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
* S1 D% A: v+ D Y; q. y& grem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs+ B+ T, N5 u0 v8 U. p Q4 ?; n
rem set PRELINK_CMDS3=...
% e e7 b! t5 r2 I3 |* {6 r9 s V
) o* T- Q5 w% [% {2 }- W:: You can have MEX run some commands also after calling the linker" ]4 ?+ q; d/ M! S H
:: (e.g. upx compress the output .mex) s8 [- `% C6 ^9 V0 F1 \* j8 t
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"+ V' u R* V) a* U5 g# c+ @
rem set POSTLINK_CMDS2=...2 o! [3 W1 v. B
8 a6 r: q6 e( Y$ Y, h) K$ p:: You can change these if you really need to. l4 F- x7 S. V$ v
set COMPILER=g++
4 P- {# B% F* H: i- eset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
) K4 h8 @7 _, V% Sset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG/ Q( ^/ n L {/ b
set DEBUGFLAGS=-g: Z3 H+ a! l+ b( x* ]- ?# s f
set NAME_OBJECT=-o
) ]6 w% G$ P1 e: M, M! y% @
$ W, t, d; w' Z G' i3 t* Lset LINKER=g++6 ~; L1 |! ^* Z! R+ J
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas
% i' o% o$ z7 E% {; |
8 g! [6 Q/ D! x1 T( t2 t* eset LINKFLAGSPOST=@%TEMP%\mexstaticlibs+ H! ^' ^9 @, }8 ?. g0 Z
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"7 P- ~/ s' [ j4 u2 ~5 Z9 ^
, c7 ?' j/ n6 |2 B9 u5 ]. I4 T O V) F
% B( O9 i. m. n( X) r! u
:: EXAMPLES
6 j2 ?( Z4 C+ j1 w6 M:: ========4 S& A6 z. F8 t( j% g5 Z8 {2 A
- ?9 u5 {& R: ~% |) \7 e4 b9 {% F
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use
( d9 [) F1 _5 N6 A% r:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.7 I# F8 ~: L1 A `! `6 i
( A v& g; x2 y9 k7 Z
:: To add include dirs, lib dirs, or compile/link flags, do:
! k5 [( d5 E5 z) q9 r- t; N( V:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
4 x I; K7 } L+ B% y G3 K0 |( N/ A3 T( O) [- z
9 {5 U; B2 b0 z7 w
选择编译器
$ H% [ f: Q& E- y; Y+ `* x- 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:. X- n& L4 D6 d% S; y+ r- D( Q2 H
- 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图: & g( n, Z3 K: w8 D) n6 k4 l! Q
- 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 6 W% n% H& ]4 M$ w3 @- A4 [
$ t1 ~2 u& n5 a8 W# W. [6 Y
) s5 T2 q" j# [. h' ~
+ \% i* f! J- L+ h* m4 P! C刚开始我也以为不能用,后来试着编译了一下,竟然可以! " F- ~; q: j: x# e1 X5 q7 B
/ e, @8 C' ^2 d; P) n3 M% B
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
7 J9 t+ }' Z) d6 z
+ X; q; T2 V6 }8 Y. N% @* l
3 e8 L) u- Y1 V0 u编写c/cpp文件: `9 k& q8 `% i5 e8 d x
与普通的C文件的编写有两点不同:5 W# u( G. s, Q5 L" f# o1 s
9 q( r; f, |, A( F1 c: x
- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。
: D/ f$ @$ k( l* f # o6 h y8 I0 l# W* R: N
! @' d2 N5 e! N T" s, i
下面以一个求和的例子说明:1 Z9 x4 u8 t& G, |' M7 u, Q! T
4 t) ?! y, B* u( r
#include "mex.h" // 使用MEX文件必须包含的头文件9 s! q x- h6 W% r' M0 {6 _
// 执行具体工作的C函数2 E6 k, Y, V+ K! D- Y
double add(double x, double y)# e6 C: Q8 ?" _5 \
{
/ a5 w/ m$ \& a! i6 p/ n return x + y;( K% D" b" U* i+ y; W9 C# D1 ?
}+ ^- A* q6 F& q4 Y8 \ L
// MEX文件接口函数
+ y$ f5 [) q; q$ }0 o9 mvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
/ W0 ^: F! d3 V{
( K8 v" P! U% c2 i1 O" T9 j double *z;5 ]+ }5 ~" {' g7 L' Q3 [8 r, V
double x, y;6 @7 L8 o+ @- f5 e& c% i1 @$ P
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);- o) F3 ?8 w" ~6 P P
z = mxGetPr(plhs[0]);
; A: F4 S7 e+ ~9 T; v! R. z/ l7 K x = *(mxGetPr(prhs[0]));, L- Z' `) _) Y4 N
y = *(mxGetPr(prhs[1]));+ W7 L. N4 ]7 ^/ n% p+ j0 ^
*z = add(x, y);5 x8 z% X9 z0 V: q! N
}- W( q# F4 E' `! @! J
; z. G6 `1 p7 j/ M
# u' U- G- A4 h4 u T2 e5 i& A; aMatlab命令窗口输入mex add.cpp,运行结果如下图:
3 u' R+ j; k7 |% X8 |
7 d9 J; m) c7 U5 t+ O* X0 w: G, p, X* Q1 {5 p! z! K9 N
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。7 @: L9 t- g* r
' S* w7 ^, {+ k. b& E/ H0 w
mexFunction函数介绍
: p( z+ V: w3 ?) o) Q- G% VmexFunction函数接口如下:) |0 G0 c% g0 R) k
2 i; p4 I$ a0 B) lvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
x% ~9 \: s P9 \' y* l/ i9 k0 A- G' m9 V& y2 D
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
8 D, R2 F) D1 P& g! a4 ^2 F% t# @& v/ p. C0 U* m6 a# I5 v
参数 意义 英文全称 类型
2 `* K) {+ H) _ a$ U A, Enlhs 左边输出参数的数目 number of left-hand side 整型(int)
. g( l* c! w% Splhs 指向输出参数的指针 pointer of left-hand side 指针数组
) A! C2 ?$ Y1 R! ?$ Mnrhs 右边输入参数的数目 number of right-hand side 整型(int) u |3 F" i! H' ]
prhs 指向输入参数的指针 pointer of right-hand side 指针数组6 _: p6 s. f' S' T- c
, _) O0 @ E% Y8 h详情参考:
! J. g% n" b2 f- `
1 y. O! S9 s% w8 v% q& ~( ?7 b4 c- Matlab参考-MEX库
- MATLAB中mexFunction函数的接口规范(转载)
- Matlab与C语言程序的应用编程接口
- matlab和C/C++混合编程–Mex
3 G% F# g. g3 b' r" T8 F
3 A: a0 V: S9 m% H6 N3 h% ~! a* S/ y5 [' Y4 C/ [, S( ~( z. B
编译多个c/cpp文件
/ x5 Z( F& R! i" |! {假设A.c调用B.c,B.c调用C.c
1 z0 X# C) G: ]! |可以使用如下命令编译:" y, P4 a5 F6 f
`5 p" d9 t/ U
mex C.c
" x% Y& S' h. y3 U3 x9 n& _mex B.c; H" f* ?: R. v0 A
mex A.c
0 i4 x% ^% ?* D9 |5 o5 X3 T1 \2 D% T" w3 u/ `4 \6 ?' d
或者
5 r& a% S/ v% y8 `: P# D
# C8 M0 W& ?, Z& @# Gmex A.c B.c C.c' M, d1 y: S% d5 u* o
1 A" F4 n3 W; b5 I* Z0 D2 W
: }9 ?+ F' M7 X$ ?- y/ n. z, u- T! J/ d, Z+ O
9 j: Y8 E4 O/ U
^! L Y6 U& V! [( W
+ R* P4 I" N- Y ~- F |
|