|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
说明
! C6 D" T+ i5 _* T2 [4 B, T, ]Matlab混合编程
5 b+ w7 x* B- Y; E1 Z. U: p 下载与安装编译器3 d) R5 U, [: p2 j" [) W# i( D
Microsoft Windows SDK 71CC
1 O% R; P+ N, d: }; G/ V5 J TDM-GCCgccg: ?6 B$ J1 U' q6 S3 Q
For Matlab 20152 B& B5 K8 y$ c2 K( k7 l$ l
For Matlab 20142 W8 r0 W* m% u" p) X
选择编译器1 g Q: a, |0 p& x2 M
编写ccpp文件/ G( ^( X8 H9 g2 e7 Q
mexFunction函数介绍$ q0 S) k# K, C( ?' v* n$ Z
编译多个ccpp文件9 k4 u$ o1 I4 ]
l& H0 f1 a' V6 {; d
2 T! Q5 L* f/ O1 T
说明; Z( v" L# a5 c+ H
记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
& c( S* J7 ]# S4 w i
: T7 A4 z9 h, ?2 B- 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)9 U& W _; O0 ?. p+ R/ S
( h; w! s+ N) G9 F7 Q# y, k- }' X, ]& p4 x7 y' L
% S! T9 ^& N& L5 P, g6 a" |. X3 Z
Matlab混合编程
( s2 ~, n @9 n2 t下载与安装编译器, V8 F6 o: F! [- g9 X
Microsoft Windows SDK 7.1(C/C++)0 m1 M8 S2 K4 [: D
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
7 \; @) e- K+ U% o
& ~9 M1 M4 A% A; Y% [下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。
; n5 |' \. `. Z- E: \# |$ Q) w" Y2 X8 N, F$ x `
TDM-GCC(gcc/g++), m: O- ?! }; N
For Matlab 2015. a, E+ P( L( U! {( d
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。: |1 E/ s( D" q. \+ v6 k% y, s
8 d+ f% s x6 u8 j8 n6 p- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
5 P* R/ t0 i5 f; r
9 U& r, k6 ~8 g, y
( A' x5 X- p7 _3 j9 j
6 U* }. T% k- j0 m+ @7 w% G- 然后,还需注意的是安装路径不能有空格;
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:+ R2 f9 l0 H3 Q% b" c# Z$ d( z0 i9 H; Y9 q
9 ^' s" l: t. i
. O9 Q! y) x1 q4 I: w
9 _; O# D: Z! {
至此完成!& f- L9 ?2 q' T9 A1 h
0 J8 j$ k: \; d$ b
For Matlab 2014
1 N$ |; q- t) F4 l9 m如下文章针对于MATLAB 2014a。
- M7 A5 L) H# R; X6 x0 P# [
7 f, w4 _0 R( L y" i点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。% j& s! p1 K) T4 n/ `0 [
8 c+ \" l, ]+ ?! u) `7 D7 d& I根据以前使用经验,安装路径最好不要有空格中文。% \* ^5 N& i0 V. X4 r) m6 F. e
) N6 ?5 {: o/ N6 P1 t安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功: * U+ D/ \3 L2 ^/ k
$ U& ^8 y. {, ^8 r; q! t
/ X% `+ e$ K" R) D0 u3 V最后的战斗: + u- n( p* N/ r5 ? m; X
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:; s/ E- h3 c: m. U3 Q- a7 V
/ J# b. f7 O$ F8 `* a, M' d4 o下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。0 m+ u. P4 U+ T; ^) ]
% F5 U" z! D* X3 g在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
1 m9 r4 B _$ L" w- h n5 w3 q
9 v$ B2 d1 _' }. a%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
T& @4 R9 _: E# W) M; G2 V g. I( \' L1 Y+ Q0 G4 x& _7 m I* w% u
下面是代码:
' O0 i' A/ ]0 X+ ^4 v r6 D! m3 i. G. j* k" f
@Echo off7 e) ~" j0 k' ?
( E; e1 o1 {3 r:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
6 Y+ [* L' f3 G9 I0 {:: parses it and only understands a very reduced set of commands:
7 K, T. `* q3 G. n ?7 \:: "set" and "rem" apparently, everything else is ignored (behaves as6 t ?6 P: q" n& e ?# }
:: "rem"), so don't do any fancy batch stuff in here. There are some
2 @$ ]! e* s$ k+ B:: undocumented special vars you can set here that will trigger MEX4 S& ?& Y; c: n3 u5 S
:: to do fancy stuff.) z% s: q0 R8 S: W5 @2 K! _
3 I7 r& f7 x0 _7 Z7 F:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
$ _3 O9 p2 W4 b# i# v/ G& _. p, M* D: Y:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/+ H$ z% O: P# f' \+ A- t% G
1 }5 C1 m2 F! J- T
:: Tested with the following:% W- G) J. _4 m* i7 ~, 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% b4 k3 M! @* n, Y9 k/ r
, J6 e( f: j+ c+ a0 W0 `
:: Set this to your Mingw64 top folder, where you extracted the above
) q* v6 A/ {! m7 a; l5 m) V8 [, rset MINGWPATH=p:\mingw64; l, \- h) }# Y: u5 m
& A& @' _6 J1 T+ D8 u! \:: Leave these alone unless you know what you're doing.
& u! D4 g+ r- S- B; T6 b6 Eset PATH=%MINGWPATH%\bin;%PATH%4 j5 o1 l* O, q+ q
set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
7 _* v! I- x( b$ E7 ~6 v1 n
0 j( k B; p$ f% c4 Z& I: e:: You can have MEX run some commands before calling the linker.8 o8 G( I6 {' E" B
:: The two examples below will cause gcc to output the full path to some
/ [: w! Y! D5 y3 V' \; x:: static libraries so you can link statically to them (see the
3 D* K. Z" t7 u. `: k3 Y9 }:: LINGFLAGSPOST special var below). You can set any command here, however.
( Z# W( K; L$ z/ i0 g& a/ T! K! hrem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
+ p$ W7 x: S3 [' ?/ zrem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
, y# j" I3 E8 h1 s$ Erem set PRELINK_CMDS3=...! k7 L$ I8 _! s. k2 ~
% [+ n7 V- r, _# ^* H1 O7 P( V
:: You can have MEX run some commands also after calling the linker
) n. J `2 j5 |. }$ u+ p:: (e.g. upx compress the output .mex)+ Q+ |* r* P5 x- F
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
* E+ @% Y2 j" T% n' Q+ }$ b* Qrem set POSTLINK_CMDS2=...
+ T$ l9 J7 Y9 M" \+ W8 v5 k7 x# p7 H9 e
:: You can change these if you really need to.
4 ~9 O5 t+ n% `' w2 gset COMPILER=g++
1 q7 Z. x8 ^- p1 m+ h tset COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE
! k2 g& X, c( t; g$ N4 yset OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
7 Y" Z9 Z/ y7 |/ R! q$ Oset DEBUGFLAGS=-g1 I7 X$ D. [, v9 D
set NAME_OBJECT=-o3 y3 c* G# M/ V
; Y/ u# r h' \# S( I! lset LINKER=g++
2 q. h6 q' J* p# L/ h& hset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas& x# } P; A( i; _; S7 H; T5 R4 E% S# f
. ^# H& c+ m2 c) n/ ?
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
& L" g( n& h8 E7 B S. H; l$ B; Eset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
1 c" p% ~4 m- |5 K, O9 K
; ]# }8 o# l& C5 j4 u7 l" c. R
( F. X# u* X' T% r:: EXAMPLES
' b5 ^$ o2 w: \:: ========$ d; o; y' j9 i! J- i, H, g" {
& p" }* U0 l* f' m1 h
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use2 d2 [- W& ^9 _! y" B
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.9 u; R% b {- Y' ?, Q
3 l* ?0 c$ N+ |+ L:: To add include dirs, lib dirs, or compile/link flags, do:
4 l' k# A& E& v6 U( I7 Z:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp. ~) V" J9 Z: O! s2 O l
0 L( [1 K9 ~# {% g v/ n7 g) p9 j! j8 d8 @$ V7 q1 e/ W
选择编译器
+ A: f! @6 \& w+ E% x5 W- 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
3 K! L, [0 K* @+ G
- 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
* f- k3 b- B1 t- a* x2 u; y4 o, \
- 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: % ], B( _) f! b/ T0 l: h
( D4 c" v2 s. j8 T, E% y E' N
' k6 M& s% F5 v8 h8 Y/ s
! ^3 }6 E0 O5 O' K+ h1 ^
刚开始我也以为不能用,后来试着编译了一下,竟然可以!
3 U- U9 w: `. d% `* g
9 ?: b. P4 F) r! n0 s. c5 _DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
3 u4 H4 e% C ]6 ] u9 [+ b# h% m, I2 P, Y- W( D
! Z- b4 N0 _$ K; {, t E6 R- j编写c/cpp文件
& A" m# ^3 t8 h" ^ v与普通的C文件的编写有两点不同:
6 b% |0 p" N7 h# k$ M! o
. L9 K2 n6 q" @+ |& F2 K- [- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。; F! N' ]5 j- a: r1 N
) L# X# \7 r$ S! A) L& P
`( p/ R7 n. N; U) P' t9 {下面以一个求和的例子说明:& w- G C2 x- N# ?; o( B( N
+ y$ M# ^' ~( }#include "mex.h" // 使用MEX文件必须包含的头文件! }+ S/ E2 v& h( u' v& [+ Q
// 执行具体工作的C函数! j2 H! Y6 }, F6 c3 ^- V, f
double add(double x, double y)! { X; h" ?- a
{4 p7 |7 X# z* x) j* W* X$ h
return x + y;1 J& S- C6 ~6 V# H
}
3 I" ?5 X+ m! h% A6 E. H$ a. J" G2 j// MEX文件接口函数
( N: M& f# O* f; Mvoid mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])) S `# I1 m! G1 M1 z" E
{
) E4 I& B2 s, B) l% N- d2 X% r! W double *z;& C4 G8 A+ a/ ]+ u+ u, Q
double x, y;+ B( Y( H# X5 _
plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);% A: E& g) v+ s v4 Q& ~
z = mxGetPr(plhs[0]);
8 z( _3 x0 Y( r* z: ~* z0 Z( [ x = *(mxGetPr(prhs[0]));4 M) ?" D0 Y% q- E5 K+ n: l5 R* O) \2 w) \
y = *(mxGetPr(prhs[1]));
, l( u" Q0 {& k! O9 g, W, l0 n *z = add(x, y);
4 Q1 h& A1 P" O4 m}! l, P8 ]+ v/ M# u& P/ `
# J+ Z& p; M- f8 q8 p6 T
7 ^* }/ {9 r% [7 t5 }$ \" i9 C) zMatlab命令窗口输入mex add.cpp,运行结果如下图:
, N# L: Q/ q+ Z4 z6 j
1 P5 c& _) D) B0 E; z; R0 @
5 Y3 f9 ` N& d$ q: ^1 W
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
) o J& I9 o: @ D* ~
% c: {' d8 @1 p& D; B+ f! @0 U3 x8 a4 WmexFunction函数介绍2 k* W1 X4 J7 G) h* f: @0 A
mexFunction函数接口如下:
7 V- l1 a* ~' C C0 _9 Z' F
& e0 z3 d, ^5 h4 `; N# Yvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])2 W, z4 H1 }1 Y$ x8 }7 x
" e$ i, l8 f% F可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
, ^# X( F! ]/ n4 v: Z* [8 G4 b2 F! A0 @7 j: P7 Z
参数 意义 英文全称 类型1 _! n% R. B! m5 l. _2 t
nlhs 左边输出参数的数目 number of left-hand side 整型(int)
" i! A- I$ v, W; j' c' c$ J' Aplhs 指向输出参数的指针 pointer of left-hand side 指针数组' R7 v' T0 j6 r; F, r) g" R e
nrhs 右边输入参数的数目 number of right-hand side 整型(int)8 u* [& \6 m0 n3 p) n
prhs 指向输入参数的指针 pointer of right-hand side 指针数组' p$ C; {8 @! _" ~- }
0 i, U1 K0 |2 a& z详情参考: \$ j; `* C9 F! g
C$ N# h( u( J4 d- Matlab参考-MEX库
- MATLAB中mexFunction函数的接口规范(转载)
- Matlab与C语言程序的应用编程接口
- matlab和C/C++混合编程–Mex4 H1 D5 D& K2 @$ }0 O3 t4 M- I, H8 G
: k- i7 `+ S7 v
0 W: C# v: R# g编译多个c/cpp文件
1 Q! h, ?. o1 P假设A.c调用B.c,B.c调用C.c 5 o3 y4 f5 l/ X- C
可以使用如下命令编译:3 u2 G! O$ c8 o* i
. q/ T3 B0 p" E4 `& u
mex C.c
$ q3 r6 Y( v" [! Z& H; h' Mmex B.c
8 f' g5 J5 G. Q) r8 Amex A.c
, [$ r) I. B- C7 w' S5 U
D' G' F, u" q* g6 ?或者9 S* k% e! d( r! Q) o' g, T6 s
9 s+ p: l" a! }' A0 N, A) w- ]
mex A.c B.c C.c
4 h' [- e {8 I1 b7 M" n& E
% B7 |4 b8 n! P2 ]8 r4 O; o
2 S6 i p, G' B6 R8 v2 J: O! ~3 a- a3 f3 e% _: ?" y0 w
1 K4 u3 Q- p/ E9 L C! m
7 Q) ^2 g6 }8 E/ E$ L8 e! q2 C
) P- n5 w+ h( F& r1 v |
|