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

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

[复制链接]

该用户从未签到

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

EDA365欢迎您登录!

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

x

1 ~; N; U0 B/ m& w: x  Z Matlab 拥有丰富的功能,编程简单。不过,有些情况下,Matlab程序的执行速度比较慢。C/C++编译执行的程序速度比较快,编程难度上比Matlab要高一些。因此存在一种方案,就是使用Matlab实现我们的实验程序,用C/C++来实现Matlab程序中比较耗时的部分,从Matlab程序中调用C/C++的程序以实现加速。" w% N6 _0 C0 U3 s) ?- \: e4 s

  I9 [/ Z) P) w     本文主要讲解如何在Matlab中调用C/C++的程序,以及如何编写可供Matlab程序调用的C/C++程序。2 F( F; I' c- h- L5 T2 W
, `. x' h6 h6 a+ X
     本文主要分以下几部分:
7 U3 D0 b! u& q" e+ p2 t9 n! R
( F$ }5 {% J% }8 X9 E     Hello Matlab,用一个简单的例子来说明如何在Matlab中调用C/C++的程序,以及可供Matlab调用的C/C++程序应该注意哪些基本事项。% T5 G; t" C0 y: p: A
& H) @0 j, V; Y0 E: S
     Matlab调用C/C++程序传递参数。讨论在C/C++中是如何使用Matlab传来的参数的。
, n0 v1 s' u% R9 p; A. T
  x; a+ }, E8 E     Matlab与C/C++混合编程的方法论。给出在一般情况下使用Matlab与C/C++混合编程的方法步骤,让大家有一个较为清晰的应用此技术的思路。) C2 A# F! F2 r: n8 a6 p. I

- L8 ^! D+ L7 w  d     关于数据存储的说明。说明数据在Matlab中的存储方式。! ?/ O) z& j7 n9 V3 I

- K* q* v5 N" h* l# {  W     注意:本文认为读者会使用Matlab,掌握C/C++语言,并且有一台计算机。计算机上安装有Windows的操作系统,操作系统上装有Matlab以及Visual Studio(比如VS2008,VS2010等)。或者计算机上安装有Linux的操作系统,系统上装有Matlab,GCC。8 o) B8 Y9 G; A" a% m& U

, Y9 R( H4 M9 }1 H
# y1 u+ h% f. Whello Matlab

5 A; i( J: s- p$ A" h8 g! E7 U     我们一步步完成一个叫“Hello Matlab”的程序。0 t; e% e8 E  a7 _( Y1 P

) T& b3 f, O, c9 Q     第一步:在你的计算机D盘下,创建一个目录命名为HiMat。在D:\HiMat目录下创建一个文本文件,命名为“abhimat.cpp”。将Code 1中的代码拷贝到“abhimat.cpp”文件中,保存。(注意,这里建立目录以及命名等行为不是规定的,只是为了讲解方便)。
9 Y8 Q3 M0 W  U) n8 H/ t8 S3 O6 q) Z3 X/ H, ~) u2 D
  • #include "mex.h"
  • void mexFunction (int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[])
  • {
  •   mexPrintf("hello matlab in C/CPP.\n");
  • }6 x' X( u: }1 y/ f3 R8 B( i# q5 v

& J' E7 ^9 P  Z! A3 B9 c" ~
+ ]* R! V# b: i0 H2 `Code 1, abhimat.cpp  u: s7 Y7 l3 F" T' k0 s9 |- P
     “abhimat.cpp”就是将要在Matlab中被调用的C/C++代码。0 q. F0 h* T. U1 p
: O2 p) P- }, p7 \5 C2 ^4 W
     第二步:在Matlab中编译“abhimat.cpp”。启动Matlab,进入D:\HiMat目录,在Matlab命令窗口中执行code 2中的命令,根据提示完成C/C++编译环境的配置。注意:如果你有多个编译器,建议选择最新的。
; N2 l. J4 h3 R3 s: C4 o. d2 s8 d2 A# x2 s
  • mex -setup
    7 V( {% O% |2 g) h

) m+ G; d( a5 {" s4 K7 w; s+ a
" m8 b* [4 n* {+ J" rCode 2, 设置Matlab的C/C++编译环境
: X! \( X# T4 H' A# h5 h) l  I4 E8 q1 B: a% z1 Y8 i" `3 D4 @
     完成配置后,在Matlab中执行Code 3的命令来编译abhimat.cpp。
9 P. R  p# U$ x- D7 X
. j; @8 z6 ]3 M9 Q- d7 Z# h7 g# L, b& {7 B/ E, h# y7 L9 F
  • mex abhimat.cpp
    + W% C$ v; n) n$ H+ g, b. n

# M+ d0 e, y! s( [' u' ^: B
) d* a7 M3 O: H) ^Code 3, 编译abhimat.cpp
( J/ r* p$ s0 k# g/ p+ m! L! e% T! J* R1 U, `3 P- p4 u* s
    第三步:执行编译后的C/C++程序。在Matlab命令窗口输入“abhimat”或者”abhimat()”,都可以调用编译后的程序,推荐使用后者。6 m# B, h/ a! L& g) p9 N2 ^
2 \: {6 |! u6 i7 {1 T
     细心的读者已经注意到了:
6 o4 T) p" R; Z! H0 f$ }2 ?, |% |* f# ]; F+ t& S* p! Q& Q
  • 在Matlab中调用的C/C++函数名就是编译后以mex*(这里,*表示任意多个字符,例如mexw64)为后缀名的文件名。
  • Matlab执行abhimat()命令后,实际执行的是mexFunction函数中的程序。- V! o) s& c$ a+ q1 ^- o8 v

; J8 Y2 C- N4 e: K/ k
" s& v# \  L0 w5 n4 T5 rMatlab调用C/C++程序传递参数5 c# L! x" w9 m2 C

5 v, {# n/ b- ~( A; E/ ^6 o    此节我们讨论下,在供Matlab调用的C/C++程序中,我们是如何知道Matlab调用的参数类型、个数的。; R/ `# ]" }4 p( z

/ p% d& L) y& n. y- b& I1 ^    给出Matlab中调用C/C++程序的一个实例,如code 4所示。
" m9 q* A" s9 ?6 b% ^  R7 A2 V% u) q" A. k

$ {3 x8 Q' S' y
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);$ V' S0 s+ D2 E/ @7 {) O0 {$ o

7 ^, o* N  V9 G/ Z* z6 D( _$ M' D4 ^% P3 i+ j4 f
Code 4, Matlab调用C/C++程序实例
6 W  k/ l( H4 M' l
2 ~4 Y6 g4 B3 h    下面的工作是如何在当前目录下一个命名为abfunc.cpp的文件中实现mexFunction函数。在这个函数中如何获得Matlab命令中的c、d两个变量的值,如何返回a、b两个变量呢。/ a) v3 [' k! F! Q% j0 y: Z/ U; X9 }
( u: I% }( p4 V/ D5 a6 E! t
    注意mexFunction函数中的四个参数,一一作出说明:( v/ u* y. |/ U

" [6 A' _! E- s" K    nlhs:mexFunction的第一个参数,它指示Matlab的调用命令中等号左侧有几个变量。例如,code 4中的调用,nlhs的值为2,因为它的等号左侧有两个变量,他们是a和b。4 l  B  Q9 B; @% X3 m2 Y0 l" Z

' N3 ]9 Q* o2 C  v6 Y; j9 F    plhs: mexFunction的第二个参数,它指示Matlab的调用命令中等号左侧变量的指针。例如,code 4中的调用,plhs[0]表示的是a,plhs[1]表示的是b。2 K3 k. q$ i; ~1 o

+ t+ }4 C4 k- |" G( m# P    nrhs:mexFunction的第三个参数,它指示Matlab的调用命令中等号右侧的变量个数。例如,code 4中的调用,nrhs的值为2,因为它的等号右侧有两个变量,他们是c和d。1 \' Y. X* C- w7 U. F! j
8 D8 o) s4 {$ d* G4 L5 M  _
    prhs:mexFunction的第四个参数,它指示Matlab调用命令中等号右侧的变量指针。例如,code 4中的调用,prhs[0]表示的是c,prhs[1]表示的是d。/ W! T: c4 M* R6 A! D: S8 M  k

1 f9 K$ s. n9 [; A) h    mxArrary是一个不可见的数据类型,是Matlab定义的,大家只需要知道mxArrary的指针与Matlab中的变量一一对应就可以了。& k  l+ N1 `8 T3 e" P
4 t9 R  U5 t# R, F* Y4 H
    下面实现abfunc.cpp,功能是a=c+d; b = c-d;具体代码如code 5所示。# Z' `9 I, C3 T0 c1 J4 n  w7 U

# ~5 U! a  F5 {0 b+ Z
  • #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];
  •   }
  • }3 J" g3 p$ V* w: M/ A8 E' W
( z$ |% q" u- i* t6 ~
Code 5,  abfunc.cpp的实现
/ Z* s+ ~% T" f, i' a7 c% A$ e  ?8 `% t% [
    说明一下code 5中用到的函数。这些函数大都以mx开头。mxAssert是断言,类似于C\C++中的assert。mxGetM获得Matlab传来的变量的行数,mxGetN获得Matlab传来的变量的列数。mxCreateDoubleMatrix创建一个2维的Matlab变量,形参分别用于指定变量的行数、列数、元素类型(mxREAL表示实数,mxCOMPLEX表示复数)。mxGetData用于获得内存中数据块的首地址。% }5 j3 u- b. ^" l, U

  P: s+ j$ I5 S! d! i5 O: g    编译并测试Code 5中的代码,参见Code 6。
, n1 \8 O5 v: W3 P, q  U; R! M6 W8 \( V2 X. s
  • mex abfunc.cpp
  • c = [1 2;3 4;5 6];
  • d = [1 1;1 1;1 1];
  • [a, b] = abfunc(c, d);
      @# A5 y+ L' U8 P' j$ |$ O

/ p8 B' g1 Q% b, b. S6 a" \# |- F1 a
Code 6, Code5的测试代码! c5 j0 F$ T1 R2 E4 {

9 s8 B0 p4 P* V0 r$ ~( q+ B    Code 6的输出结果如下:
6 s) k8 P$ t/ h" u* Y$ f
. b8 L  N) n+ o$ g8 X# b3 u4 n
  • a =
  •      2     3
  •      4     5
  •      6     7
  • b =
  •      0     1
  •      2     3
  •      4     5- L! W2 J+ y) F
% `$ S+ ?: t  X) T' E$ s% w4 ]6 d
: k0 ^7 Y, I& J
关于数据存储的说明) B2 H5 K% O' ~" B0 [
3 Q2 M" |. I7 D) U
   Matlab中的数据是按列存储的。例如,a=[1,2;3,4;5,6],a的数据在内存中的存储顺序是:1、3、5、2、4、6。在C\C++中使用Matlab传来的变量时,一定要注意数据的存储顺序。
+ a$ U( Z; q% U+ ~7 U  E0 l
6 Y5 Z0 F! x' O+ p3 Y7 h
2 T2 ?7 O* q2 [: [" z0 Z; O! ]" qMatlab与C/C++混合编程的方法论
- C; \, {2 M! T, g+ o9 q( m$ C( [
, X4 e. o% C  J& V, o( H鉴于@编程小手 的建议,添加一个关于使用此方法的方法论流程图。希望它能让各位明白在什么情况下可是使用这种混合编程的技术、如何一步步实现。参见图1的流程图:
# n( y& V9 m- y' M% D. `0 L( ^4 q" o

4 Y9 M  ]$ ^4 `+ P" F9 p( D* i
9 d$ ~$ V$ ~; P6 H2 g- g, o7 n: P; Y图 1、Matlab与C/C++混编方法论流程图
' n7 H' e# y. E# K: Y: i  y, C5 Q

该用户从未签到

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-5 21:18 , Processed in 0.156250 second(s), 26 queries , Gzip On.

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

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

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