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

初步研究一下C/C++与Matlab混合编程

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

' e7 P1 c. f0 ?/ c Matlab 拥有丰富的功能,编程简单。不过,有些情况下,Matlab程序的执行速度比较慢。C/C++编译执行的程序速度比较快,编程难度上比Matlab要高一些。因此存在一种方案,就是使用Matlab实现我们的实验程序,用C/C++来实现Matlab程序中比较耗时的部分,从Matlab程序中调用C/C++的程序以实现加速。. y* T: Z: i" @" }0 {( i
- u, O9 b5 r+ H8 [  K
     本文主要讲解如何在Matlab中调用C/C++的程序,以及如何编写可供Matlab程序调用的C/C++程序。# K7 S, D: U% E" Q6 j7 d
- u0 B7 P9 j5 u( g7 Y! q
     本文主要分以下几部分:$ V! ?, I+ J3 ]0 ^# U* V% }5 |. U

( M% J  M/ t+ N) K- E3 v     Hello Matlab,用一个简单的例子来说明如何在Matlab中调用C/C++的程序,以及可供Matlab调用的C/C++程序应该注意哪些基本事项。
  Z, W0 q1 [, I+ c
/ |$ \& D" {0 I  C( _: [     Matlab调用C/C++程序传递参数。讨论在C/C++中是如何使用Matlab传来的参数的。9 Z3 F% Y+ m1 B3 s! V
" y: m, n+ K+ I7 L; f, u
     Matlab与C/C++混合编程的方法论。给出在一般情况下使用Matlab与C/C++混合编程的方法步骤,让大家有一个较为清晰的应用此技术的思路。
3 z+ b8 Z& o: L8 z! q$ o
/ i2 f  s! `" N1 w+ R3 X     关于数据存储的说明。说明数据在Matlab中的存储方式。8 T7 z% g' i" n  X  V
9 S, n0 x6 c7 n3 w0 n. L
     注意:本文认为读者会使用Matlab,掌握C/C++语言,并且有一台计算机。计算机上安装有Windows的操作系统,操作系统上装有Matlab以及Visual Studio(比如VS2008,VS2010等)。或者计算机上安装有Linux的操作系统,系统上装有Matlab,GCC。
. \7 `& @- N1 \3 m2 W5 \9 ~" ~  P9 }8 l! l

9 k/ \( O$ C( {" h3 B' A) Whello Matlab
( d7 d; p- \" \
     我们一步步完成一个叫“Hello Matlab”的程序。) R& N% T' |. p% W: V
9 I" _" K" S4 S* X/ e
     第一步:在你的计算机D盘下,创建一个目录命名为HiMat。在D:\HiMat目录下创建一个文本文件,命名为“abhimat.cpp”。将Code 1中的代码拷贝到“abhimat.cpp”文件中,保存。(注意,这里建立目录以及命名等行为不是规定的,只是为了讲解方便)。
% C; f; u5 z) K/ A5 V8 Y; z
  B" i+ V0 [7 v9 m  u
  • #include "mex.h"
  • void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  • {
  •   mexPrintf("hello matlab in C/CPP.\n");
  • }; v1 U" @, V5 o
. K0 Y$ w' t3 F" U+ @  X+ B

/ c. ]0 P, `+ A6 v  \/ b5 gCode 1, abhimat.cpp
$ ~6 `& r) C1 H& ~8 V$ T     “abhimat.cpp”就是将要在Matlab中被调用的C/C++代码。
; a# e$ l/ x# W4 _0 G; H/ }4 C. l6 `0 E# a
     第二步:在Matlab中编译“abhimat.cpp”。启动Matlab,进入D:\HiMat目录,在Matlab命令窗口中执行code 2中的命令,根据提示完成C/C++编译环境的配置。注意:如果你有多个编译器,建议选择最新的。) `! V5 `1 J: R0 T/ G

  h* D: p; r2 ~$ j
  • mex -setup6 e# d- t/ C4 h# v, z2 f
3 o# q( p* c1 K1 [- M3 p

+ W' x  Y3 x" o) W* H3 |" q; wCode 2, 设置Matlab的C/C++编译环境/ I  B% n3 t6 k& Z# X- R# Y8 |1 O
2 r1 g/ \' W6 A% E% m2 p
     完成配置后,在Matlab中执行Code 3的命令来编译abhimat.cpp。+ p- I, k* P& y6 V9 v. [- J
! l$ F4 p! l8 G: Y- {0 B* ]+ v
' t0 e8 D0 F4 u! K
  • mex abhimat.cpp0 |: W& ^! S  k& x; u5 D5 m8 n
2 X. s  P, ], D/ G& [$ z

0 ~7 F+ r" l4 Y  c: R& N& I0 t/ ?Code 3, 编译abhimat.cpp
# m6 f/ n' E5 u7 B1 @( y  m6 [# \1 a' s9 S/ r* n# A- n! t
    第三步:执行编译后的C/C++程序。在Matlab命令窗口输入“abhimat”或者”abhimat()”,都可以调用编译后的程序,推荐使用后者。
. _% _- _; D0 d' L/ P7 Y$ O3 c) V' U, f. j3 K5 a5 |
     细心的读者已经注意到了:0 ], a5 k. o9 F. k9 v8 }) b
( [$ Y, b# ?! ~$ T$ w. G* X+ k  e
  • 在Matlab中调用的C/C++函数名就是编译后以mex*(这里,*表示任意多个字符,例如mexw64)为后缀名的文件名。
  • Matlab执行abhimat()命令后,实际执行的是mexFunction函数中的程序。3 Y: t2 ~  I' A
% P8 ^8 W7 u5 K1 B, e

% a8 k) y6 M% J( u0 VMatlab调用C/C++程序传递参数% m$ q3 R& e# _- f5 w" f* I
; p1 @* g+ b& ?
    此节我们讨论下,在供Matlab调用的C/C++程序中,我们是如何知道Matlab调用的参数类型、个数的。
2 f" R8 C! g* n; q7 R% K7 R' P, T5 c
1 \$ Z) w+ I4 k: D    给出Matlab中调用C/C++程序的一个实例,如code 4所示。: N6 n9 i9 Q0 V2 D" C! b& D) v

8 @9 e/ b9 j4 U7 B0 i  H, i
# P6 Q8 d/ E3 ?/ [3 y' `
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);% _  a0 \  L% }1 {. F( s

0 M$ u; [& ~7 G. x
1 K  g$ q# w# \Code 4, Matlab调用C/C++程序实例
* C, u  h. f9 g4 l! h! p
' h1 `$ @) N( e# m* B    下面的工作是如何在当前目录下一个命名为abfunc.cpp的文件中实现mexFunction函数。在这个函数中如何获得Matlab命令中的c、d两个变量的值,如何返回a、b两个变量呢。8 Z) ~2 B; R2 x6 o) G6 H
3 v  Q/ }- H& O/ b# @8 ?
    注意mexFunction函数中的四个参数,一一作出说明:
4 t' Y$ L9 j6 n7 c
0 ?% f  A# d5 u1 h* F    nlhs:mexFunction的第一个参数,它指示Matlab的调用命令中等号左侧有几个变量。例如,code 4中的调用,nlhs的值为2,因为它的等号左侧有两个变量,他们是a和b。" \, s4 c6 B" }0 K) p/ c. |

7 J" s. E, z2 g: y% }1 O2 V; B    plhs: mexFunction的第二个参数,它指示Matlab的调用命令中等号左侧变量的指针。例如,code 4中的调用,plhs[0]表示的是a,plhs[1]表示的是b。
# H" l% Y( u' y/ _1 {/ z& M9 ]$ v' t, S
    nrhs:mexFunction的第三个参数,它指示Matlab的调用命令中等号右侧的变量个数。例如,code 4中的调用,nrhs的值为2,因为它的等号右侧有两个变量,他们是c和d。
8 y% e# l& B' [0 x7 L5 N  r  N4 L  `" v0 i  p. j
    prhs:mexFunction的第四个参数,它指示Matlab调用命令中等号右侧的变量指针。例如,code 4中的调用,prhs[0]表示的是c,prhs[1]表示的是d。& A7 i* [6 i$ _; V
/ s: p' e4 f$ E* U$ t/ w
    mxArrary是一个不可见的数据类型,是Matlab定义的,大家只需要知道mxArrary的指针与Matlab中的变量一一对应就可以了。6 G# Z( S' S: P& ]; K& p& Y6 p: W( H
9 i- f  F) n; _7 q0 {* V; ~
    下面实现abfunc.cpp,功能是a=c+d; b = c-d;具体代码如code 5所示。
/ B0 }) _* N8 c9 b7 u* X6 r& o+ d" @3 h+ ~3 M% q7 Z. j; K% @
  • #include "mex.h"
  • void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  • {
  •   double *p_c, *p_d;
  •   double *p_a, *p_b;
  •   int c_rows, c_cols;
  •   int d_rows, d_cols;
  •   int numEl;
  •   int n;
  •   mxAssert(nlhs==2 && nrhs==2, "Error: number of variables");
  •   c_rows = mxGetM(prhs[0]);// get rows of c
  •   c_cols = mxGetN(prhs[0]);// get cols of c
  •   d_rows = mxGetM(prhs[1]);// get rows of d
  •   d_cols = mxGetN(prhs[1]);// get cols of d
  •   mxAssert(c_rows==d_rows && c_cols==d_cols, "Error: cols and rows");
  •   // create output buffer
  •   plhs[0] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);
  •   plhs[1] = mxCreateDoubleMatrix(c_rows, c_cols, mxREAL);
  •   // get buffer pointers
  •   p_a = (double*)mxGetData(plhs[0]);
  •   p_b = (double*)mxGetData(plhs[1]);
  •   p_c = (double*)mxGetData(prhs[0]);
  •   p_d = (double*)mxGetData(prhs[1]);
  •   // compute a = c + d; b = c - d;
  •   numEl = c_rows*c_cols;
  •   for (n = 0; n < numEl; n++)
  •   {
  •     p_a[n] = p_c[n] + p_d[n];
  •     p_b[n] = p_c[n] - p_d[n];
  •   }
  • }) o% V0 g. B5 ~# t, f
0 n5 F# ?( k6 [8 u( o! K
Code 5,  abfunc.cpp的实现
8 i' T7 ^% q' Q
0 q+ k& Q$ n. W1 N    说明一下code 5中用到的函数。这些函数大都以mx开头。mxAssert是断言,类似于C\C++中的assert。mxGetM获得Matlab传来的变量的行数,mxGetN获得Matlab传来的变量的列数。mxCreateDoubleMatrix创建一个2维的Matlab变量,形参分别用于指定变量的行数、列数、元素类型(mxREAL表示实数,mxCOMPLEX表示复数)。mxGetData用于获得内存中数据块的首地址。# }* X4 g# P/ O- t" r' T; `
( l! [0 h# ~1 i( I% q/ Z8 t, E
    编译并测试Code 5中的代码,参见Code 6。
0 z: Y1 n9 l' w3 L
4 P3 P0 |5 ^$ C9 o# l: T
  • mex abfunc.cpp
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);9 \0 |  z. p3 [
: q1 x: Y* C6 K0 N. q" r$ ^: b
2 ~& B/ `) v" b7 n+ m2 [- D
Code 6, Code5的测试代码# U6 j- h( o) D+ o$ R: F" ]

% r/ P! u7 H- G; y( d9 q  d    Code 6的输出结果如下:& W2 H/ _" N8 [1 y
. r* i; k/ w9 i7 u4 p* e
  • a =
  •      2     3
  •      4     5
  •      6     7
  • b =
  •      0     1
  •      2     3
  •      4     5
    * p' X7 q+ W; d1 V9 f$ ^

: c2 `3 E$ p7 N% P$ d2 u* M. a) C: Z" f6 w5 p
关于数据存储的说明
# X9 ?: q5 I7 K6 g+ e& n, u. O
0 s! x" @0 x4 E( q9 |   Matlab中的数据是按列存储的。例如,a=[1,2;3,4;5,6],a的数据在内存中的存储顺序是:1、3、5、2、4、6。在C\C++中使用Matlab传来的变量时,一定要注意数据的存储顺序。
2 v7 N% \7 W( W/ O' j$ B! |) N$ a
! S3 Z& d) y" q6 {, F/ V" q+ i' ?2 y
Matlab与C/C++混合编程的方法论
% w; I4 }. n) e, k- N8 Z8 n- H; o) p, ~8 i
鉴于@编程小手 的建议,添加一个关于使用此方法的方法论流程图。希望它能让各位明白在什么情况下可是使用这种混合编程的技术、如何一步步实现。参见图1的流程图:7 j) M- c9 D9 E* j$ w/ z

. P1 `: N9 r* U4 J+ _* C& `; t
: H$ x# p. a* H& \
8 K, T& L; O. S- _8 Z* ]图 1、Matlab与C/C++混编方法论流程图
: W% X& [% V! R: Z

该用户从未签到

2#
发表于 2020-1-7 18:06 | 只看该作者
C/C++与Matlab混合编程
  • TA的每日心情

    2019-11-29 15:37
  • 签到天数: 1 天

    [LV.1]初来乍到

    3#
    发表于 2020-1-8 19:14 | 只看该作者
    C/C++与Matlab混合编程
    您需要登录后才可以回帖 登录 | 注册

    本版积分规则

    关闭

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

    EDA365公众号

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

    GMT+8, 2025-11-23 20:27 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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