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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x
  f" t1 Q( j& ]* s6 _
Matlab 拥有丰富的功能,编程简单。不过,有些情况下,Matlab程序的执行速度比较慢。C/C++编译执行的程序速度比较快,编程难度上比Matlab要高一些。因此存在一种方案,就是使用Matlab实现我们的实验程序,用C/C++来实现Matlab程序中比较耗时的部分,从Matlab程序中调用C/C++的程序以实现加速。2 ~! P3 f$ g# W2 k# F8 j" ~
& f# C0 R0 ^5 ]! B0 h- d
     本文主要讲解如何在Matlab中调用C/C++的程序,以及如何编写可供Matlab程序调用的C/C++程序。4 O! J3 P& c  \( L
1 ]  M" g# N5 A2 K5 c
     本文主要分以下几部分:- q8 ^* w8 R- N- ~
5 c0 n. |' Y# J3 @. {; ~$ f
     Hello Matlab,用一个简单的例子来说明如何在Matlab中调用C/C++的程序,以及可供Matlab调用的C/C++程序应该注意哪些基本事项。+ m7 j, |" _( D2 T" P* u1 P* M. S
' i3 p6 ?; |- g0 O+ j1 P
     Matlab调用C/C++程序传递参数。讨论在C/C++中是如何使用Matlab传来的参数的。
6 F* x( X% W, F- f! I$ B& Q8 e
' T) g8 k! b" A# n. _( z4 {8 x* t     Matlab与C/C++混合编程的方法论。给出在一般情况下使用Matlab与C/C++混合编程的方法步骤,让大家有一个较为清晰的应用此技术的思路。
( H! f: W* a6 `7 Y' W1 d
5 [2 P& e$ c/ m% Y" ?     关于数据存储的说明。说明数据在Matlab中的存储方式。
8 C% K, ?( n* F* H2 p
- c; U$ z; Y0 L) v1 @4 p8 c     注意:本文认为读者会使用Matlab,掌握C/C++语言,并且有一台计算机。计算机上安装有Windows的操作系统,操作系统上装有Matlab以及Visual Studio(比如VS2008,VS2010等)。或者计算机上安装有Linux的操作系统,系统上装有Matlab,GCC。$ m+ q5 M7 C4 [0 ?' I

- I2 e! o  W" e5 ~; q- I/ Y# G( x- F5 U9 I& g! H0 G- k
hello Matlab
! F- B; ^1 X6 ?# }8 ]4 i% k$ r* r
     我们一步步完成一个叫“Hello Matlab”的程序。
5 v7 F8 d/ h" s/ ?, _5 H
. c6 h6 m$ l8 B7 s0 [     第一步:在你的计算机D盘下,创建一个目录命名为HiMat。在D:\HiMat目录下创建一个文本文件,命名为“abhimat.cpp”。将Code 1中的代码拷贝到“abhimat.cpp”文件中,保存。(注意,这里建立目录以及命名等行为不是规定的,只是为了讲解方便)。, c8 j% |1 D; m- k6 u, k6 Z- c, s

2 E1 `" i5 x6 q7 M$ `
  • #include "mex.h"
  • void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  • {
  •   mexPrintf("hello matlab in C/CPP.\n");
  • }
    / r$ V- i$ c. P7 _; ?9 M' B/ z( r
: Y& n5 X$ N- C) Y

; V% \- I7 i+ lCode 1, abhimat.cpp: |3 c: Q0 A4 O- s
     “abhimat.cpp”就是将要在Matlab中被调用的C/C++代码。7 W8 Y1 a) P' J: `

9 S) S* R1 j+ J1 Q" c7 y& t  W     第二步:在Matlab中编译“abhimat.cpp”。启动Matlab,进入D:\HiMat目录,在Matlab命令窗口中执行code 2中的命令,根据提示完成C/C++编译环境的配置。注意:如果你有多个编译器,建议选择最新的。1 X% d: `1 ]5 y' E9 J
5 W, j* r- h0 f, O- g5 q0 P9 @
  • mex -setup! i$ o- w2 \( t- A
, U7 F/ n# Q9 L$ u9 f

1 c) e3 b- {7 e4 d9 P: qCode 2, 设置Matlab的C/C++编译环境
. ?/ ?. g. H( D
$ `! ?! O3 Z2 P0 r& P     完成配置后,在Matlab中执行Code 3的命令来编译abhimat.cpp。
8 N( @% \- `' w% p7 K
2 n. Z- \- o! K+ U; A) B7 X
/ F& f6 w8 Y7 A% S/ w) K1 A
  • mex abhimat.cpp
    . L5 Y6 ]/ \& I; n* w9 V  }
% `* m/ H% ~' d2 k
3 {4 v% `) s8 m7 r
Code 3, 编译abhimat.cpp  J2 b. ]6 p8 M! V3 R8 N) ^

: ]3 N3 f( l  }8 P* u    第三步:执行编译后的C/C++程序。在Matlab命令窗口输入“abhimat”或者”abhimat()”,都可以调用编译后的程序,推荐使用后者。# J7 a/ I1 ]) @# I$ ^- J& K" w

4 e+ x) y2 [) e     细心的读者已经注意到了:# l. T; Q% z. h6 o  l7 f% w
5 Y  @. q0 X. D. J/ d$ D
  • 在Matlab中调用的C/C++函数名就是编译后以mex*(这里,*表示任意多个字符,例如mexw64)为后缀名的文件名。
  • Matlab执行abhimat()命令后,实际执行的是mexFunction函数中的程序。# G9 N# k) s/ C, ~7 }

2 q0 ^0 q$ A$ a( i- h0 P, \0 p4 U  v
Matlab调用C/C++程序传递参数# ~# m/ B8 Q. ?* C, ?
: f& [, {, t5 g3 k
    此节我们讨论下,在供Matlab调用的C/C++程序中,我们是如何知道Matlab调用的参数类型、个数的。
9 C" ?! f, S9 u
1 i7 A! I! f& q( g  n    给出Matlab中调用C/C++程序的一个实例,如code 4所示。
3 y! F" q! Y4 S+ Z, I8 g" S3 h5 o0 t9 Z

- N6 ?0 ^( w$ _& a" r: J1 `) v5 @: q. O
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);
    , o8 Z0 H+ k; U* a2 D
5 U8 F4 {0 G; i2 p6 v
: P: u) B( t* u" k, T' i. a# {
Code 4, Matlab调用C/C++程序实例8 M7 E* o. z6 e$ o! P* O: z- `
% b+ I" d( @' x5 m
    下面的工作是如何在当前目录下一个命名为abfunc.cpp的文件中实现mexFunction函数。在这个函数中如何获得Matlab命令中的c、d两个变量的值,如何返回a、b两个变量呢。
$ W2 Y5 F9 @0 A7 n5 M$ X2 U; m2 I: L" N& Q& P5 ?
    注意mexFunction函数中的四个参数,一一作出说明:
7 \2 H- V% J* n; P+ z7 m, R5 k2 H( s+ R8 }7 C# B
    nlhs:mexFunction的第一个参数,它指示Matlab的调用命令中等号左侧有几个变量。例如,code 4中的调用,nlhs的值为2,因为它的等号左侧有两个变量,他们是a和b。& t& K9 G4 l6 Z2 f, `% S
/ L) T( ^+ L8 t: k, V- u5 u* l; t
    plhs: mexFunction的第二个参数,它指示Matlab的调用命令中等号左侧变量的指针。例如,code 4中的调用,plhs[0]表示的是a,plhs[1]表示的是b。# j  G# c+ a( c1 S3 ~1 i) b7 h

3 e" w9 b; R; q- \1 C5 J& T: T    nrhs:mexFunction的第三个参数,它指示Matlab的调用命令中等号右侧的变量个数。例如,code 4中的调用,nrhs的值为2,因为它的等号右侧有两个变量,他们是c和d。
; z) s/ C( K! i# j. o
+ I/ g$ y4 M: L2 K    prhs:mexFunction的第四个参数,它指示Matlab调用命令中等号右侧的变量指针。例如,code 4中的调用,prhs[0]表示的是c,prhs[1]表示的是d。5 Y' z# l0 W( K7 E2 S( M
  Q0 n# R9 \( _5 H4 y4 i
    mxArrary是一个不可见的数据类型,是Matlab定义的,大家只需要知道mxArrary的指针与Matlab中的变量一一对应就可以了。
6 n; Y; i0 I, k+ q; w7 f
' M3 C) F( S& L. N, P3 ~2 U/ L    下面实现abfunc.cpp,功能是a=c+d; b = c-d;具体代码如code 5所示。7 Y7 J5 n3 y1 W5 d

' r' z$ B3 D# b: @
  • #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];
  •   }
  • }
    & {' X* L, |0 O, A0 V9 J
' D1 L. u0 \0 _5 J3 h2 n5 D
Code 5,  abfunc.cpp的实现! n' o" u2 e( W

. L9 p4 \- `; @5 I0 j+ T    说明一下code 5中用到的函数。这些函数大都以mx开头。mxAssert是断言,类似于C\C++中的assert。mxGetM获得Matlab传来的变量的行数,mxGetN获得Matlab传来的变量的列数。mxCreateDoubleMatrix创建一个2维的Matlab变量,形参分别用于指定变量的行数、列数、元素类型(mxREAL表示实数,mxCOMPLEX表示复数)。mxGetData用于获得内存中数据块的首地址。9 B# x1 ~' b1 w: i5 G% W' ~

' S4 [" s1 ~: H0 @" L    编译并测试Code 5中的代码,参见Code 6。1 B! Y- B7 g; u1 D; i- _
# y" z+ G) {. z5 ?
  • mex abfunc.cpp
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);
    7 C9 R; n/ N* W5 u
  _. H4 w4 ^+ k! H

+ d6 ]# n7 ]5 Q2 kCode 6, Code5的测试代码- s% m" I* \& v5 W* W$ L' L
; a3 I6 U% U9 M
    Code 6的输出结果如下:, v! w3 H2 F# E* A; Z( |* l" _& K

5 c  \; H  S* V3 Z# m6 H
  • a =
  •      2     3
  •      4     5
  •      6     7
  • b =
  •      0     1
  •      2     3
  •      4     5  D. \; U1 W, x0 ^$ f2 J" F( M
% S& @  U; R0 X5 O( U2 X

* |  j0 ^; ^, ~% ]% g* B/ V, |& J关于数据存储的说明
8 d% H* i1 g* z9 P: o0 Y6 _- E: W  j$ r0 Y! T5 |
   Matlab中的数据是按列存储的。例如,a=[1,2;3,4;5,6],a的数据在内存中的存储顺序是:1、3、5、2、4、6。在C\C++中使用Matlab传来的变量时,一定要注意数据的存储顺序。! E; t) L$ f# W0 W! R8 a8 Y; F
: p' f3 f, Z& ^

$ V4 j' J) L  m3 K% Z. A7 p+ yMatlab与C/C++混合编程的方法论  o2 i- `( ?2 H. N3 s& |+ T

% `2 s+ S1 g3 R3 x' E8 Y/ i鉴于@编程小手 的建议,添加一个关于使用此方法的方法论流程图。希望它能让各位明白在什么情况下可是使用这种混合编程的技术、如何一步步实现。参见图1的流程图:+ {" s4 F' @5 [+ y+ h" i% A
4 i3 i5 N9 M( g% ^

0 e6 w& a8 E4 P/ {
* j% I+ k4 J) y% F  o, ~. D) L图 1、Matlab与C/C++混编方法论流程图
" w! `1 r3 I; D' j: A# T2 A

该用户从未签到

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-10-31 19:47 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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