|
|
EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
说明
/ P3 ?2 p+ R; X* d; k2 y3 MMatlab混合编程) Q) F5 [9 J2 {1 @- c0 t6 U4 S
下载与安装编译器
$ F" v9 w, f' ]+ |/ D Microsoft Windows SDK 71CC, X8 P3 w2 T7 s) i
TDM-GCCgccg t# o b9 ~. w% t$ J3 y" {
For Matlab 2015* ]' P& s! f0 \' C% c6 a
For Matlab 2014
1 P `* }1 u# r' ] 选择编译器
$ O: ^# {; ], t; q, b( y 编写ccpp文件
! Y, C5 K/ z; q8 S$ H mexFunction函数介绍
* S( Z/ b' _. o' ~6 Y! j! o 编译多个ccpp文件
2 o, m2 M' x/ V! e$ M6 u# A! k$ w- ~$ B
% D5 u$ S6 w) t$ l说明
9 C% B$ K v0 l2 ?0 b& y* p7 Z记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。2 _$ \3 c( Q9 P" m, e' n
7 m* Z" M* ?* p! X6 i, \
- 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)
$ L) e" m/ N& ?4 g 7 L* A+ j1 s* X% X
. w1 B" U6 A, e3 p1 T+ Q3 b6 A+ s2 A1 Y9 q& N7 k2 \$ ?* Q s
Matlab混合编程 e& d" _6 x; K: N
下载与安装编译器. k! o4 n# c* p& Z
Microsoft Windows SDK 7.1(C/C++)7 `* \( {9 U; t2 c+ M1 H5 X" G
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。
9 N+ \ @1 H% q! H& ?. u+ h
/ r: ]/ V. n. y. D8 z下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。' G. x) ~ g' P. d' F
) R/ b% B3 g7 A9 ?- L! ^TDM-GCC(gcc/g++)2 L% W" _, y/ {& H2 Z% d
For Matlab 2015 C5 s9 R5 r" D
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。) K5 c( r, n. R L2 m
( h) M$ s( o1 _7 P, Y! K- ^- 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:2 U- g( X9 c4 _+ }% A/ Q
' _; K3 J+ d0 `: Z Y! ~ D
8 V* u7 p* W& T+ u, k0 ~! k; L! z2 X0 _8 v% w; M% s( g7 R- t2 l: L
- 然后,还需注意的是安装路径不能有空格;
- 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
- 重启系统和MATLAB后,输入mex -setup显示:7 t% I) U+ N& Q( Z$ e$ ]
& m2 Y6 q2 S" n# {- J
9 o. R" @! ^4 t( y- P- x& A$ r. f5 |
7 [! A3 S" b* U, a& `+ o+ Q
至此完成!" [! A, _& [9 O1 ^
" O7 w& K. Y: H; D5 V3 ]7 q* k7 Z! c) Y# d
For Matlab 2014' e: F3 s+ J6 s0 p+ J' h3 r+ F
如下文章针对于MATLAB 2014a。( _3 a R5 a( X$ q% w; g
; U+ P+ y3 J& ^8 E点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。2 d, c* Q* ]8 Y1 d9 ~; c4 S& M
8 A9 b! N7 m0 t7 a根据以前使用经验,安装路径最好不要有空格中文。& w( Y! x0 s- K( l0 h
7 f4 }+ U% }: j+ {9 C. ~9 m$ q3 P
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
( C' @4 [( J- T, W& ?* F8 x
: T3 |% g$ N% n5 ?9 ]- W* f
^' z: @( Z- k5 w3 }, I最后的战斗: " f; h; `# H% @1 e% y) v
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:2 o8 G- f9 q) N" O
4 L0 ]/ ?- R1 v8 P# Z/ K5 N- {, g1 x下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
# r5 z# d' K: b, ~3 Z3 n2 b/ f c7 i: {
5 w) ]3 N; k0 |在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
J$ w7 }$ Q' s0 g. t3 {8 s1 O" y( z& D0 X$ G2 I3 P5 i. _+ ^8 I
%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
2 x6 B J( u! s+ v4 Z3 [% t d0 q# q3 e2 Q& ~
下面是代码:/ U1 M3 f. A) p0 u! p
9 C2 M/ Y: ~) v3 X( [ q- |
@Echo off6 b, |* l5 b! \2 D
0 G) I: n" Y' U) b6 h
:: NOTE: this is actually not a proper .bat file executed by Windows. MEX5 w' g+ |' [2 |# D8 V4 x
:: parses it and only understands a very reduced set of commands:
7 L u" a7 z( N9 h:: "set" and "rem" apparently, everything else is ignored (behaves as
9 q- D1 v% |' [1 c+ m8 s:: "rem"), so don't do any fancy batch stuff in here. There are some
6 {) T; Q# b& r; ^* v# w:: undocumented special vars you can set here that will trigger MEX
# m5 }+ e* |2 S: E( o:: to do fancy stuff.
/ V) M$ X6 K/ [: m1 b, h8 o* ~$ {4 [: V/ k4 s
:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:6 ?. Q0 i( E2 |( E. c! |5 F
:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/
% n9 H" F+ B, k+ I9 V S& C1 \& t
# g1 T. ]* i' N( R:: Tested with the following:
6 {3 A# C2 M6 F9 e/ W0 ~:: 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/ x# u$ p" W; a% \, }8 l
% t. ]9 @8 E3 E( i$ K) Q9 A& V
:: Set this to your Mingw64 top folder, where you extracted the above
, K. b) l$ n/ a2 k4 M9 y; ]7 dset MINGWPATH=p:\mingw646 G2 q: l* W% `: u9 S7 I
5 ]/ @$ h5 k0 {. g) O) u; M5 Y6 ~1 D
:: Leave these alone unless you know what you're doing.
8 ~9 E+ c) y$ N7 ?set PATH=%MINGWPATH%\bin;%PATH%# T% @6 |; w$ n# Y9 _( x7 @1 D
set PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
2 ^ F; _' T6 l1 g, y: T1 E" ]! @9 w$ `# _; N
:: You can have MEX run some commands before calling the linker.
, T1 ~. k# e0 q: X. g3 b! }" L, y; s:: The two examples below will cause gcc to output the full path to some
* Z- f! c5 G7 z+ M9 H$ w:: static libraries so you can link statically to them (see the1 p: E) F- ^9 g7 ~9 | |
:: LINGFLAGSPOST special var below). You can set any command here, however.
* @, S5 r6 E9 F! W( vrem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs
8 v: [2 z! f: O! U/ p, \rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs- Y1 ?/ _. u% @& u) |2 |8 Q
rem set PRELINK_CMDS3=...
2 S4 h! O4 q3 F: M, X' [
! L/ O6 I* k, ^: h, V) ~:: You can have MEX run some commands also after calling the linker% ?2 U0 @ m) y ]
:: (e.g. upx compress the output .mex)
; q9 [ p% }4 O' S( U# n( wrem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"4 U6 i! i# a3 u, O4 P& f
rem set POSTLINK_CMDS2=...8 ]$ ~9 x- _! w7 g
+ F1 W) E$ o+ Q. X8 b- J:: You can change these if you really need to.+ S" S' n1 u& l/ P) s# h. Z( Q
set COMPILER=g++# U; q5 ]8 V; m0 u$ N5 z2 M; z! `: J
set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE$ W8 Y: i/ Q4 H1 d/ T& w$ }
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG
( u. \+ T8 C( H6 x6 P4 ~set DEBUGFLAGS=-g
! `$ \6 L+ s3 A$ V4 X" G) N8 k. \) Tset NAME_OBJECT=-o
5 l8 X; L' L3 L' X, Z0 _
* k/ s) Q3 {7 d7 u9 k2 m( Cset LINKER=g++* N! h4 U- B( W2 v* R( s
set LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas2 \/ |; x$ g2 Q$ J, [
1 I' d5 D% h3 k, i( s
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs5 `+ O6 W! C- v! O( {; A
set NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"
8 [& e( x9 F5 C9 O7 F9 k% ?, u$ h+ s7 g: o \
( x$ G( l% _5 P# U:: EXAMPLES/ t1 U, z3 q; [7 h+ {3 L g8 V) v7 [
:: ========
8 C) h) a: f0 @: J1 V9 f* S) D8 Y. h) V8 _
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use5 ~7 ~- W1 b P, v" c
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
) O7 H/ w: T# `% Z8 u: r3 a. T: J0 A: P: ?- f9 p8 y; b
:: To add include dirs, lib dirs, or compile/link flags, do:" F- {9 U. t2 X4 i& [) J
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp
" a6 N! \+ a; u; q* x8 ]- y; v
, w: |! Q/ m7 w w) H" M5 R
5 S( w5 ^; W3 L+ t9 S选择编译器& @1 i, y) S$ ~) O5 O$ P* o
- 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:9 n: f& R, x( M2 J6 G6 v2 d
- 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
* \$ F! X. A$ Z M6 x+ t
- 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 8 T" x5 o+ B. u0 [ X% z% _
( q2 m: V6 D# |+ B) ~# @5 e
# h1 r+ R- K; k3 j3 k- J5 s0 @" _0 t; {8 T( A3 |* T; ]9 l, E
刚开始我也以为不能用,后来试着编译了一下,竟然可以!
# |( P" v, ?3 W& B$ _1 {$ c
- Z8 ~* L& J# g; p% I% [8 y; q
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!4 `, n( w9 V9 J/ ~. z. n
) y. K0 n" V1 G8 L+ t* n, t. L z3 u; D. d
编写c/cpp文件
+ b* L9 I: [9 d( [0 u% P与普通的C文件的编写有两点不同:
3 ^3 c' M) R" E" ]
$ g5 a( s) b" D6 J, `/ H2 e- 包含mex.h头文件,即:#include "mex.h";
- 编写mexFunction函数。+ G4 ?# `) p& K
/ R: n7 p3 W9 _$ x [# B5 ?2 b& M7 b, _
下面以一个求和的例子说明:
: @, b+ ~4 X o3 {( v5 u5 ]- N, X) M6 z: k
#include "mex.h" // 使用MEX文件必须包含的头文件' B% f! O6 J3 t
// 执行具体工作的C函数% |% O4 \. E J0 ]# a+ H4 O
double add(double x, double y)$ [% ]4 `; T0 ?, M
{
) j+ [+ q1 o6 _( ]3 P: } return x + y;* ~5 N4 u- z0 f0 u- w, c
}* u/ R! P& F4 u6 }1 ]
// MEX文件接口函数' L4 W* N3 p/ M3 ^2 `
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
: U! F/ F4 b# H# z/ s- E{. R# `/ G& ?' k
double *z;
4 S& f7 n7 T3 H' ^- m8 @" c double x, y;
5 l I& x. |2 ^9 o plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);5 [2 i: V9 w+ U6 h' s" E
z = mxGetPr(plhs[0]);9 N; {+ `* h9 \
x = *(mxGetPr(prhs[0]));
9 W }8 Y+ c! V& k" L+ q+ K y = *(mxGetPr(prhs[1]));
9 g" F3 W0 W' @ *z = add(x, y);4 ^8 Y; v4 j1 p2 E, T
}3 g8 [1 Z0 ^$ Z! E1 y1 c
5 ^% @! d9 d. Y. U
" k+ J1 P" v; ~! R. qMatlab命令窗口输入mex add.cpp,运行结果如下图: 0 E; F1 K( R9 {: v' g
% y* A# Y4 V* u; c& m; b: |0 w1 E, R$ M# D3 w4 h* ^. ?
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。
" E" I* I9 q* e( K/ a2 k1 K& g; p$ L1 ]5 q: E3 W3 o
mexFunction函数介绍
" |5 C/ R7 A- e$ O( ^& h3 V' FmexFunction函数接口如下:
5 P) ]) M6 k* H3 ^6 m
# @, @& l! K# @& Y+ pvoid mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])5 C! d& z, x: d
! x2 g* B; D+ a( E* a! I$ X1 @
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
$ u( E1 P& h! f2 j5 } g+ t o- _* v" b H" @) k
参数 意义 英文全称 类型5 T$ Q" ], v* B5 B& f1 F8 y1 a
nlhs 左边输出参数的数目 number of left-hand side 整型(int)
o! T7 t: c. i1 l3 J( Aplhs 指向输出参数的指针 pointer of left-hand side 指针数组
5 @' _& C/ P6 j( ^6 K& V5 V6 j4 Xnrhs 右边输入参数的数目 number of right-hand side 整型(int). [7 u5 D V2 q
prhs 指向输入参数的指针 pointer of right-hand side 指针数组
% x% G$ H; P( p, _% r, ~% S3 s7 i: V) B7 Q
详情参考:/ C3 d" J. T" w/ t V: i$ X
& _% b* E9 G3 l/ @2 R/ L
- Matlab参考-MEX库
- MATLAB中mexFunction函数的接口规范(转载)
- Matlab与C语言程序的应用编程接口
- matlab和C/C++混合编程–Mex
( @0 F- F, [" D$ F2 f8 |1 j0 v % P' X2 Q0 i, ]8 r; g6 N L
6 ]' J6 W4 s9 a! |4 A) h编译多个c/cpp文件, ]* L, ]8 y) S9 m2 b/ p" |( F0 L
假设A.c调用B.c,B.c调用C.c / }( u: A" n, h- Z4 y1 v3 v* D5 h
可以使用如下命令编译:$ L/ T" Y0 W6 C) Y
8 m& ~8 \+ A- V- A2 C; ~mex C.c
* q7 h6 a K7 \# n& F; @mex B.c6 X/ ?8 s) Q; T7 U2 }
mex A.c
8 u, g+ G8 }) r4 R& u {7 H
! f* y, x3 `. ^$ D- A/ h0 t: h" J或者6 W1 }" e2 N5 u5 M- H
6 g, A% K8 @6 ~/ t$ ? @1 p: g* X6 c0 zmex A.c B.c C.c
: r$ _9 Q, v+ ], c9 b1 e
* K% C. w8 b- G; _) ^# x6 G3 [& n' Y2 n: d4 o# K
) c# B2 X7 {9 ~5 s$ Z" U+ A5 |& i0 @/ _* p4 O! p$ d0 l
8 U( W) T0 }# d: c% `* y' M P+ C" u2 J8 K4 s$ F3 {& {! C4 S
|
|