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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
说明
  }: e; E# O4 @+ Y( XMatlab混合编程7 c% \8 o0 B" k" Q5 L1 _
       下载与安装编译器
% Q) l: h1 M% C* }7 B/ T0 N0 G              Microsoft Windows SDK 71CC
- |/ ]" n  `2 ]9 _+ L              TDM-GCCgccg: I. W, C& N# }/ i  d/ ^% c8 R
                     For Matlab 2015
9 V% j/ v7 V4 K                     For Matlab 2014, ~' A5 R' H$ g8 x( L) f- V. ]+ J
              选择编译器
* w& M2 [' D( K+ I, k+ f              编写ccpp文件7 O1 Y/ E# F2 t+ o
                     mexFunction函数介绍
) j; O6 j0 a( b6 R/ ]' \* B              编译多个ccpp文件
2 K0 j* v# i& {2 r) o7 i8 n4 ?6 C  N! u

6 ]3 e$ j' G2 g0 J4 c8 s; @) s说明
" z  D+ `, Z" z$ r. x: I记录本人在Windows下,使用Matlab 64-bit 版进行混合编程时遇到的问题,主要记录编译器的安装与简要的混编过程。
& z3 v$ ]& s0 w( p8 Q) n3 r4 ^6 z7 P' w. i" o7 r. P3 w6 T* g1 B8 B% L
  • 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)
    . `: A; o! V0 |$ {$ \; z6 }: P
6 ]1 C; ]  A+ T, @' M, P6 R$ a4 S' U
0 }) S  Y/ Y9 r! I6 Z+ Z2 D3 P
) A, z' G- m, A6 Y9 P7 T0 B
Matlab混合编程# k1 A) H9 F0 }2 s( [, K1 G
下载与安装编译器
) s2 N0 d* M7 ~% U" U( LMicrosoft Windows SDK 7.1(C/C++)8 f! g# |" m( j" G
点此Microsoft Windows SDK for Windows 7 and .NET Framework 4 (ISO)打开下载页面,是镜像文件,选择64-bit版,文件大小500M+,全部安装需占磁盘近2G。; k; `) ?8 S" o3 e

# }, d7 @' k, |4 Y% t4 `/ _% g下载完成后根据提示安装即可,如果出现问题,安装失败,参考:Problem&Solution 部分。* D" H! J, w) ]2 g8 o+ L4 w) Y
2 O( t% A0 [8 O+ y0 {( s
TDM-GCC(gcc/g++)
; j" u" a: J- ?( T3 \1 r! X, QFor Matlab 20159 w3 j, Z8 @* h3 y4 o
Matlab 2015已经开始支持GNU编译器,具体参见:Supported and Compatible Compilers for R2015b,安装方法参见:Install MinGW-w64 Compiler。
/ W% l# n( y5 d0 K+ d
' L! g9 P6 }# P
  • 注意,MATLAB 2015现仅支持GCC4.9.2,在安装TMD-GCC时,不要勾选更新,如下图:
    $ Y4 _* g3 W, Q2 D% s% y' M
7 t* m/ u8 L9 n4 P8 P& I6 e- y# J
2 h/ ~* m8 n6 n/ _7 L

: I5 T' ?/ y6 g0 C6 z& A' V7 a
  • 然后,还需注意的是安装路径不能有空格;
  • 需要添加系统环境变量MW_MINGW64_LOC=your tdm-gcc path。
  • 重启系统和MATLAB后,输入mex -setup显示:9 P) u  v5 Q& B* y/ F

. N& i8 @) N3 N# l3 G/ `; k% W  E + M) H0 r  t9 t+ M5 y
( c6 S2 Q# O4 T$ ]: {
至此完成!
* @7 _, b4 V6 ?" A& Y2 |+ Q
& }6 \1 C8 t' H2 GFor Matlab 2014
+ t) _; t( O( y1 w7 B0 U如下文章针对于MATLAB 2014a。* p) N" E0 g8 H! ], o3 u

' r$ V. T" r# k' {  n点此tmd-gcc打开下载页面,选择64位版本,40M+,全部安装占用400M+磁盘空间。
2 z6 K6 G( h& i! _% _! o5 f& O3 @: n+ a
根据以前使用经验,安装路径最好不要有空格中文。- F5 R" f* A$ G2 t2 z0 c, I
- T& J' @& y; |! y; @1 Y$ l6 T
安装完成后,开始 -> 运行 -> cmd打开Windows命令窗口,输入gcc -v,如下图所示,显示安装信息,说明安装成功:
2 v. N, D+ J  Z: x 7 d  M3 f) c* c, t& I
3 c7 S. x6 N+ J3 t9 c' f" \
最后的战斗: ' c1 B% d& \0 T: ?5 l; C7 N/ \
因为Matlab不支持GNU的编译器,还得做点事,下面的方法来自Using GCC (MinGW) as MATLAB’s MEX compiler 中的Bogdan的解答:' t6 a8 [5 L: ~# V- O3 o' S

  r5 e; T# X! ^/ M! r/ v8 P下面的代码是从Bogdan主页上下载的mexopts.bat文件代码,使用时需要做一点小小的改动。
9 D% Y/ E7 L0 ~7 e* ]* ?5 V
+ N( @4 g0 M: a) G" Y! |在下面的代码中找到:set MINGWPATH=p:\mingw64这句代码,将其中的路径p:\mingw64替换成你的TMD-GCC-64的安装目录,如我的是:E:\devtools\TDM-GCC-64,然后保存并将mexopts.bat文件copy到计算机如下路径(复制下面的路径地址,粘贴到资源管理器窗口地址栏,回车即可):
' Y" S; U0 ?5 Z: ~! a& p( a6 t
4 o+ u$ I6 D) ]/ o$ j%USERPROFILE%\AppData\Roaming\Mathworks\MATLAB\R2014a\
8 x* P( _( G: o( I$ M* D' h1 O# B# p8 [9 ~# d2 _/ k* X
下面是代码:
  ?( ]2 ^" P: D. S* _; O3 C& x4 q+ c  l' w
@Echo off
: l  z6 T, M  D- S3 J& d: f
; p- f6 P6 ?; q:: NOTE: this is actually not a proper .bat file executed by Windows. MEX
- V( y: @, v' @::       parses it and only understands a very reduced set of commands:' ~; D3 A  r' w
::       "set" and "rem" apparently, everything else is ignored (behaves as
: j8 }5 w7 q1 E$ I::       "rem"), so don't do any fancy batch stuff in here. There are some
: e4 T+ Z  J7 i6 I::       undocumented special vars you can set here that will trigger MEX3 I% T) u5 }5 d. p
::       to do fancy stuff.; J+ S" B1 b" O

1 d: |) Z" G8 `1 t:: You can use MinGW64 builds (win32 threads + seh unwinding) from here:
7 N5 Z- Q+ g5 l$ ?:: http://sourceforge.net/projects/mingw-w64/files/Toolchains%20targetting%20Win64/Personal%20Builds/mingw-builds/; ]7 g7 y2 C. m' m1 i4 h) E+ _) G

5 u1 R+ B  Y: N:: Tested with the following:
/ q5 N% ]6 ^; Y" I& c6 k# e:: 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
5 `$ Y0 X3 Y5 r" ]9 V4 u6 }: K* J; x+ z' Q, N9 C- I! P& u# {
:: Set this to your Mingw64 top folder, where you extracted the above# M0 v1 O+ t" P1 E% U9 G& |
set MINGWPATH=p:\mingw64
) p+ p8 `) b4 a, ?. v6 o3 l! M4 P0 V% M% b4 z% W% @: F
:: Leave these alone unless you know what you're doing.4 Y" i! }. b7 R, {. m& c
set PATH=%MINGWPATH%\bin;%PATH%
5 u$ |3 E9 ^/ U4 S& aset PRELINK_CMDS=echo.>%TEMP%\mexstaticlibs
# A6 {* G- \0 `' G$ Q; m9 R& j4 G6 y
:: You can have MEX run some commands before calling the linker.
; F. d4 t& g3 T& I8 [4 _3 X:: The two examples below will cause gcc to output the full path to some
! h4 _. W" Q2 \( e& U:: static libraries so you can link statically to them (see the
* {3 H& T6 j7 V6 E5 A:: LINGFLAGSPOST special var below). You can set any command here, however.1 w  F, f0 _' I& U
rem set PRELINK_CMDS1=gcc -print-file-name=libwinpthread.a >> %TEMP%\mexstaticlibs$ u5 C8 R9 ~0 Q, o
rem set PRELINK_CMDS2=gcc -print-file-name=libquadmath.a >> %TEMP%\mexstaticlibs
. D9 d$ d1 C; `$ u8 mrem set PRELINK_CMDS3=...6 n8 ]2 @, j- Q( ~0 V

9 k+ p% K. C3 N, |' w:: You can have MEX run some commands also after calling the linker" v( Z; a7 Z, c" j9 r
:: (e.g. upx compress the output .mex); y% B. U" g1 t# |) C8 S
rem set POSTLINK_CMDS1=upx -9 "%OUTDIR%%MEX_NAME%%MEX_EXT%"
8 g9 g6 h" a% n: F) X7 C1 Mrem set POSTLINK_CMDS2=...4 ?, c2 Z7 f& Q& j0 [, N3 m
! B: A7 [9 D5 u8 F
:: You can change these if you really need to.
" \- i& T8 V1 v4 t9 aset COMPILER=g++
2 Y3 ?$ M' Z* L( t% Z  {set COMPFLAGS=-c -I"%MATLAB%\extern\include" -DMATLAB_MEX_FILE6 S1 P- H# o, Q/ P( B4 r  j
set OPTIMFLAGS=-O3 -funroll-loops -DNDEBUG7 _/ _! ^2 a$ T; O, a) ?3 U
set DEBUGFLAGS=-g
- O# R3 M# A! l% D0 \set NAME_OBJECT=-o
$ R* _, \* q; E4 |' M9 }7 v* q, n: p+ T$ n% B' h
set LINKER=g++
6 V, x  U' ^6 K; {2 Vset LINKFLAGS=-shared -static-libstdc++ -static-libgcc -L"%MATLAB%\bin\win64" -L"%MATLAB%\extern\lib\win64\microsoft" -lmex -lmx -leng -lmat -lmwlapack -lmwblas, i4 I, A1 q$ N; f! M
. g! U! n" ?! w6 y  d% Q$ g
set LINKFLAGSPOST=@%TEMP%\mexstaticlibs
1 N" G8 \2 ~/ P# s- h) Zset NAME_OUTPUT=-o "%OUTDIR%%MEX_NAME%%MEX_EXT%"9 h( E- G5 e/ `4 {% W% o
& o& q4 H% b: M/ Z  q: _# ~
/ e- [. ]! f% L; Z' M
:: EXAMPLES
# X, R; w( J, k& X6 j) {4 p:: ========8 e5 u$ ?% l/ \
( T6 E7 N# F0 r8 G( Y/ _
:: You can compile simple files using "mex file.cpp". To support more than 2^32 elements, use+ l& t& c1 [, l) S$ s; y
:: "mex -largeArrayDims file.cpp" ... use this by default, unless you know what you're doing.
# O# u% e( F. y6 c
3 K) y* A$ O, Q0 D$ a:: To add include dirs, lib dirs, or compile/link flags, do:( J4 A( e% L: K3 I; G
:: mex COMPFLAGS="$COMPFLAGS -std=gnu99 -Ix:/include/dir" LINKFLAGS="$LINKFLAGS -Lx:/libs/dir -lmylib" -largeArrayDims file.cpp: Y- o/ A% Q: H% @: G8 z
& w% W% I& D  F2 `# X) z+ f
. x8 H" M3 X0 h2 Q
选择编译器6 d% M5 C7 m  O# i
  • 查看可用编译器:使用mex -setup查看可选择的编译器,如果没有需要自己安装,如果已安装且只安装了编译器Microsoft Windows SDK 7.1(C/C++),显示如下结果:
    / ~7 I5 o- v$ j! c7 k
  • 选择编译器:使用mex -setup lang选择编译器,如mex -setup C++选择C++编译器,如下图:
    * A5 }4 e6 l+ r# M5 F
  • 如果你也按上面TDM-GCC(gcc/g++) 中讲的方法,配置了TDM-GCC-64位的编译器,那么,你会发现结果如下: 3 [4 h& ]( X8 \* K0 M2 A9 ^
    & @% O) F4 ^, V4 \% x
% S+ }4 W0 ^6 I  f/ [

9 G( C) ]! p1 b7 E4 t8 ~刚开始我也以为不能用,后来试着编译了一下,竟然可以! : Z  S8 ^3 m. ?# `) X" C
       3 W0 n2 U! `& W) ]2 ^+ s
DT.c文件中重复定义了无穷大,注释掉,就没有提示啦!
) q0 y0 C4 w) M
6 U6 n0 C7 v9 ~% b
* \' N0 H5 S4 w% e5 [& [' u/ J; i编写c/cpp文件
/ p! m! |+ f' X与普通的C文件的编写有两点不同:
5 D% B" [9 e! E' C
- Y5 \' z( {  V7 h% t  q
  • 包含mex.h头文件,即:#include "mex.h";
  • 编写mexFunction函数。
    9 i: ?! D* F* I' ~# @8 a

% D$ _  ?: g' Z4 }3 ?4 S' W$ Z* F4 Q2 e- t9 w* h/ d7 e0 u
下面以一个求和的例子说明:* g& n3 u4 U2 _0 S" z. R+ f

& Q0 @& E3 X. s% ~& Q4 e0 l9 G+ P#include "mex.h" // 使用MEX文件必须包含的头文件- g- Y4 [. S) R  ]
// 执行具体工作的C函数
& v2 B8 Y& [# c, ddouble add(double x, double y)7 u2 J1 o* A+ g
{9 n; v( _& ?9 i: M
    return x + y;& B: r- ~+ c. e6 X0 O# s6 ~0 W* g/ _! e
}0 `! k& W6 h+ D! [  g( }$ u
// MEX文件接口函数& j9 z7 v( S) O2 n* y0 V" n
void mexFunction(int nlhs,mxArray *plhs[], int nrhs,const mxArray *prhs[])
: Q/ j3 E+ w: W+ `! t6 [2 w{, q6 ?( U( }2 n. `
    double *z;+ N2 a& i8 S4 r0 \
    double x, y;
: p0 ~) U( l; e    plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);5 a! H! B6 p! p  D* R  a3 c
    z = mxGetPr(plhs[0]);. j7 I4 y- ?2 v( d! z* O6 s1 \$ J4 C
    x = *(mxGetPr(prhs[0]));6 N& q# @/ R# V( w
    y = *(mxGetPr(prhs[1]));
" ]& f8 S; p& {2 U    *z = add(x, y);
$ Q5 c2 c# Q' X, y2 u( p) Q# i- x1 r}
/ R  q& t/ y# m; _/ W# h/ q- i3 R5 c( e% ]& W

: H# t5 u& L- y% u; V! \6 ~Matlab命令窗口输入mex add.cpp,运行结果如下图:
$ J6 M8 _3 ?0 \
  _' v3 p/ @! j, }  O, Y" S" R: ]; Z0 D" {3 C/ N. ~0 i
在Windows上编译后生成mexw32和mexw64文件,在Linux上编译会生成mexa32和mexa64文件。. u' K  @8 f; G$ W/ f9 l) O
6 A8 N* x" X6 Y8 f* ?4 }
mexFunction函数介绍
4 k6 T1 L5 Y& H( t3 [1 o2 SmexFunction函数接口如下:
8 b/ q! W# N! ~% d6 F2 X5 k# h( ^) f; m+ Q6 x! q
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
# ?' y9 v! [* n3 i" G$ t/ L. O3 e# X2 F" G/ e
可见,是没有返回值的,其实是通过指针数组plhs传递的。它共有四个参数,即左边的输出参数及数目和右边的输入参数及数目,具体参数意义如下:
8 {2 |! |8 q6 i! Z9 ~, V
, p# N; `4 I/ V2 p0 D! \参数                  意义                          英文全称                 类型
: X2 {( Y0 Z7 @7 v+ Z* enlhs        左边输出参数的数目        number of left-hand side        整型(int)/ [* ^6 R3 s7 I4 \' _
plhs        指向输出参数的指针        pointer of left-hand side        指针数组
! c; Q0 o5 d2 O! mnrhs        右边输入参数的数目        number of right-hand side        整型(int)
" ~- D& g2 o* x" t* w0 ^prhs        指向输入参数的指针        pointer of right-hand side        指针数组4 S1 Q5 V/ E+ ?9 b7 x6 U) m

9 ?$ {& @- z+ V) x2 J详情参考:
& Q' p8 r  W% o% r6 ^# X, h) L3 g* z
  • Matlab参考-MEX库
  • MATLAB中mexFunction函数的接口规范(转载)
  • Matlab与C语言程序的应用编程接口
  • matlab和C/C++混合编程–Mex& h# \3 t7 b; C+ H7 @( R4 W3 @2 c

* S$ F' F& l+ k! o& c1 G2 {- N% w" Y- H' x
编译多个c/cpp文件
6 T8 `; E8 j5 ]- o$ H假设A.c调用B.c,B.c调用C.c ) m- h/ t) m7 h. f" G
可以使用如下命令编译:
8 C1 u( {' v; u& [0 \) p0 X1 o  S4 v. v: W7 R: z7 i
mex C.c, y5 \) `4 a9 A1 D) K6 w' ^9 \4 ~
mex B.c% `$ u. o6 I* Z# B
mex A.c
6 s: D1 o; r( O1 _8 a# v3 t# R% c* v0 l; \0 Y, d8 C
或者  ]/ E* R" l3 R8 J  H
9 K; Y9 |2 |2 z/ A4 m7 [
mex A.c B.c C.c
& B3 m0 X$ L. u$ R# n8 z: @& d5 |9 k: \# c  L. R9 e

9 c  m! F2 \2 U! i+ Y, p! S1 C  X6 `) q' S- w& O% E

- r" `8 O9 }) n% \2 M& w* u- N6 N$ U! f
$ c! V% G. H% |( T- N) o+ K

该用户从未签到

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

本版积分规则

关闭

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

EDA365公众号

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

GMT+8, 2025-11-4 16:45 , Processed in 0.171875 second(s), 26 queries , Gzip On.

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

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

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