QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4486|回复: 10
打印 上一主题 下一主题

[课件资源] Matlab调用c程序

[复制链接]
字体大小: 正常 放大
梦溪517        

18

主题

5

听众

230

积分

升级  65%

  • TA的每日心情
    开心
    2014-2-12 10:47
  • 签到天数: 52 天

    [LV.5]常住居民I

    群组Matlab讨论组

    群组C 语言讨论组

    群组学术交流B

    群组学术交流A

    群组2013年数学建模国赛备

    跳转到指定楼层
    1#
    发表于 2012-8-28 20:47 |只看该作者 |倒序浏览
    |招呼Ta 关注Ta

    2 z. I; [. W6 w8 YMatlab调用c程序& m, b6 V$ ?7 _5 J1 e+ [# `
    文章来源:不详 作者:佚名
    8 b; ^0 y5 w7 r$ W
    8 _+ E+ V, R+ z7 |) I2 B9 V--------------------------------------------------------------------------------& [) |; Q+ B3 F; [# i6 d- _
    5 g. M" @' Q+ k/ q( K* Q
    该文章讲述了Matlab调用c程序.' Q0 M$ j7 o6 }2 ?
    4 w, i( y- y* `! @+ o( C6 [
    方法:
    ' x0 _' \2 p4 ~7 Z  ?0 s/ |第一步:要先在matlab中安装c程序编译器,步骤如下:
    3 v1 {6 f, B2 ~- F5 p$ W- Q键入命令:mex -setup
    9 \3 M. ^2 k% m* ?选择c/c++编译器;8 C! }. o; e6 d* n( u9 _
    选择c/c++编译器版本;
    " c; l- @( Q' d0 j: U确认。, I' V' }1 X* V# I0 v1 L, v
    第二步:键入:mex *.c
    ' n2 u# O1 Z/ Q2 ]) e; u; c2 V8 K' ?9 o3 v2 D, p1 C. y
    *********************************************************************************************************************************************: M4 z9 X. |" C/ `7 I$ Q, T
    : V/ U4 y: y+ e9 Z. \
    实例介绍:【转】: j, K& ?+ H; _# |4 I6 g: B1 t
    ( W" M2 H. w2 W# Q! @
    如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
    # m& v( P6 x! C# ?% Q3 L) Zdouble add(double x, double y) {
    5 Y. w2 D" o' @" s- S: R4 l return x + y;; Q' Z3 H  }3 ~& P" ]  i; b
    }
    9 N$ {/ U( a% ^  o现在我想要在Matlab中使用它,比如输入:
    & X0 p) r4 g* n, I* e, F2 I>> a = add(1.1, 2.2): U5 Z+ _" |8 w4 \
    3.3000# @' i# ~" v' R* I# B; \
    要得出以上的结果,那应该怎样做呢?+ {7 ?, n+ b1 G' T: [9 c' Y% \& `6 n
    解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。2 M7 O6 r4 v* J' }2 q, E4 r- I
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。# ~+ n+ D; X: `; B+ q0 `
    所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
    6 X7 _" O1 W) I; I0 V& S( n& C0 e  O: @比如该C文件已写好,名为add.c。那么在Matlab中,输入:9 N' L+ ]4 j9 u: y; V$ Q, a
    >> mex add.c
    . `2 _* N; M, Q; c! n) T0 {$ }就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。2 }! w# l' g6 P, D7 J' u
    我们现在来说mexFunction怎样写。# x0 Z% G; a! p; [! W4 N* P: s; }
    mexFunction的定义为:! M$ x0 H6 g$ s% ^; S
    void mexFunction(
    + K3 H3 c3 m* T2 p0 @/ x; E4 h     int nlhs,* O0 V# H1 a- o' W: z; w/ M
         mxArray *plhs[],: n  F3 I# o( s1 P& u
         int nrhs,7 N! p/ y- a) G; A# E6 K
         const mxArray *prhs[]) {/ m- B+ F9 U7 b' z' c9 M

    , D$ C* b3 b2 M+ q( ^. K}) Z3 ]1 Y7 l+ E! r- b" d
    可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
    # ^9 `5 W% a( C9 V: ?>> b = 1.1; c = 2.2;+ K  f! E% t% [+ W+ [3 h" K9 h
    >> a = add(b, c)4 k% k$ I9 t3 T
    mexFunction四个参数的意思为:
    ) Z( e2 e( \! U6 Cnlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a
    8 k' @6 N! |  B) H, f! N( E  h) Hnrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc, m: V( N# R7 j
    plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a# T+ q. |2 o, u5 H6 Q9 u6 H
    prhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。
    # e( P- Z6 l, _) g因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。) l  `3 v7 E# H, V2 R5 Z
    完整的add.c如下:' D* ~' g) Z/ c, I7 e
    // add.c5 ]$ H, y& S# Z6 j$ M# f& s
    #include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数* X& b8 W; b/ b6 [( b* m! g& V! a( _
    double add(double x, double y) {$ D- d  {# n+ D$ J$ w9 L
     return x + y;
    3 j+ X' s4 C, e- F8 b. q  K} // MEX文件接口函数
    # l- v6 _: k4 z2 e# f+ g; @4 avoid mexFunction(1 ]' a2 d( v+ O! D1 {7 C2 ]
     int nlhs,
      C! _7 m' Z# _( ?1 h% y& R mxArray *plhs[],
    3 F' b, B- ~3 m, ~ int nrhs,) S5 x4 {! i9 S
     const mxArray *prhs[]) {% u1 F. {7 ?( f! P
     double *a;
    ) ~$ G- J! M  S, E+ | double b, c;
    8 v9 _( [: u4 w3 f  ~4 n, ? plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);7 a+ M' ?  Q$ L+ A# n7 e
     a = mxGetPr(plhs[0]);3 k; h# F. y# X+ J9 b- R8 l
     b = *(mxGetPr(prhs[0]));, G: l  E6 Q: E+ ]  W# F! W
     c = *(mxGetPr(prhs[1]));2 [& L& R+ b# |  {/ O/ C! w
     *a = add(b, c);! d& Y% U4 E8 c, X4 A3 q
    }
    % C( S8 Z1 D3 z  x1 Z" EmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    8 d  N+ ]# m( B8 ?/ A8 I7 |1 a>> output = add(1.1, 2.2);) P( q. L) a2 k6 K) E1 N
    在未涉及具体的计算时,output的值是未知的,是未赋值的。所以在具体的程序中,我们建立一个1x1的实double矩阵(使用mxCreateDoubleMatrix函数,其返回指向刚建立的mxArray的指针),然后令plhs[0]指向它。接着令指针a指向plhs[0]所指向的mxArray的第一个元素(使用mxGetPr函数,返回指向mxArray的首元素的指针)。同样地,我们把prhs[0]prhs[1]所指向的元素(即1.12.2)取出来赋给bc。于是我们可以把bc作自变量传给函数add,得出给果赋给指针a所指向的mxArray中的元素。因为a是指向plhs[0]所指向的mxArray的元素,所以最后作输出时,plhs[0]所指向的mxArray赋值给output,则output便是已计算好的结果了。
    # V1 i  J5 z' F上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
    1 w; c3 [4 b; I' l( I实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
    / r7 w9 i  y6 T- Y: o5 f- `& B输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
      R/ _4 _: e( g# Z& b从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。6 q4 X& m2 d+ D

    + ~/ }8 c/ O* k; P( f9 w*********************************************************************************************************************************************
    5 w' P2 N$ O. |6 O  W2 H8 Y% b: q" [0 q" |# V+ v
    mex 的目的,8 s; V& x! B6 f$ F" f* e
    7 Q! N5 M8 h+ K* Q6 y6 Z2 w
    通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:" l' s# ]* x' a3 I1 `8 n. m( Z
    : w3 H( o9 \  k  H* S* j2 z7 @  e
    1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.
    1 P; ~  R; [/ S' s) O; ^7 t7 O$ J$ y
    ( V! m) I- t4 e% x2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.
    % H( |3 N/ E8 _$ K
    7 |! o5 ^% D  @3、据称可以弥补Matlab硬件设备接口的薄弱环节.; }' Q- s: G, R" D; B" I) V. G- f

    : h. A0 ]% s9 }- n9 b+ q今天写了第一个使用MEX.
    + x8 i3 ~6 i5 p7 F! x' f! c
    2 s( Q  o! p4 x9 y& I0 ~一个简单的对Matlab普通数值矩阵的操作.7 e( {4 ~) N- D
    8 t6 o; {; P( H8 R/ u: r
    其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以
    + w6 V5 C. ~5 h  [& j2 Y0 a/ L
    7 {, f+ e% Z7 z7 p一律用int代替.
    5 z# N* I' v  {/ D- D6 W( p& A- v0 a1 {6 Y/ J
    #include "mex.h"
    ; z) f0 y' a" `#include <iostream>
    ) _2 h4 m4 |* G5 D5 z2 V4 \
    9 X5 |. ^$ c! t, W* vvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])/ Q) T" y! D( @- J
    {  O  Q0 F, z; e/ D7 q

    0 ?" T; C/ }, D6 f/ w& ~8 kint i,j,k;
    & z5 @8 ~) x' Nint index;; _/ `. V0 M' d& i
    double* pr=NULL;
    6 K% [& W+ k1 b4 G; Q3 y  ddouble* pi=NULL;0 d) n/ {, |' v3 j: P: T
    int M,N;
    & e1 u" ?# [: f* f6 D6 a" ^int ndim;6 L. d* l, i; K6 l
    int dims[2];# i0 z& |5 }) K$ N/ K+ R+ g
    for (i=0;i<nrhs;i++)
    ' ^6 K+ A4 `4 L& B7 Q1 A{
    ) P3 r/ f  e. y- k1 E4 X' W' J   if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2)): W- a" Z$ w. }& n2 K
       {
    $ T% {5 h2 r  _    pr=mxGetPr(prhs);: ?% T/ Q) t$ T* g" u) j4 ^
        pi=mxGetPi(prhs);: Z$ ~  L6 l" Y- ^9 A3 o
        M=mxGetM(prhs);
    - u3 C8 N, j6 N, C( X6 z    N=mxGetN(prhs);0 {) s( s+ ?+ o# ]' Y9 @
        ndim=mxGetNumberOfDimensions(prhs);5 L: u3 t. b% Y1 s- ]
      U' k5 X! d) m4 E+ k
        mexPrintf("变量%d:\n",i);
    0 V' J. k/ Z3 o: V+ K0 A) h6 k    for (j=0;j<M;j++)" R* F3 j2 v  H
        {1 G! w7 ~$ P5 L7 I6 l) N7 z+ \
         dims[0]=j;# Z% X6 ?8 ?$ D  M/ c
         for (k=0;k<N;k++)
    2 Q2 j) C/ \) }; o! F8 Z% r     {
    5 V. M+ E/ M  W) c      dims[1]=k;
    4 S: G+ W/ c1 \7 m+ A      index=mxCalcSingleSubscript(prhs,ndim,dims);  Q1 g( y( r) M6 f0 y6 W. k, a& _
          if (pi==NULL)6 z& q+ D3 y, Z& R$ U
          {
    $ D/ O$ m$ d) U       mexPrintf("%6.2f",pr[index]);9 {% g( d9 b% p! L  y' D( K
          }
    * Z+ k8 S- W7 j, {) b5 [+ Y      else{, N& C4 S8 {5 |' g  r
           mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);- f. I$ A0 E- |8 s3 y
          }
    8 K* ^& C5 l* s5 {4 M$ L0 d     }
    8 F2 F9 S4 j- ?/ n     mexPrintf("\n");
    ) ?, x- d5 D4 D( _( |" \$ i
    & v8 N: \! y7 @$ W" c, y) d    }
    * Z4 c# \4 X: ]  
      q! z/ Q1 u6 H6 L4 Z2 N   }! Z; b6 ]2 S" n) a* i7 A( Q
       else{8 Q0 k/ R* ^2 j' @
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);; ~; d5 c; e. u2 ^2 z; i
    }2 a& @$ d8 f/ t& m; ]: N+ Z
      X: u* F9 @( X# C4 u' @  x

    1 X, ~) }# E0 M% i( t}
    & y" ]: K( Y' n6 f3 {. d# }6 h6 \/ p! F. L! [* J" n
    }
    ) n- l5 _" m: g% o: B, [4 ]$ X+ V0 |2 {
    Result:2 j6 }( N1 \$ A! l0 e

    2 X  b/ Y) t! g; [6 l>>mex test.cpp( C! x- C0 X+ x* y2 R" E
    >> test(a,b,c)
    2 i5 M3 d, `* i- v$ q变量0:, }+ l2 E3 V) E2 e
    0.35 0.62 0.83
    : t" @, Y, ^: ~0.20 0.47 0.59
    - W  x; |! _( r0 N0.25 0.35 0.556 I7 d& q8 u. e5 p. i5 B3 H8 J
    变量1:/ k8 ]$ e' ?3 v* x  q2 r; C
    0.92 0.38 0.53 0.57
    , n2 ?+ M* H* A3 L0.29 0.57 0.78 0.47
      ?6 L; J5 _  s# }, _9 F  b0.76 0.08 0.93 0.01
    3 B+ O/ b) c+ J% Y+ z, Z1 Q/ J0.75 0.05 0.13 0.34
    . A/ x0 w" L1 M: R4 v% |变量2:
    2 |  B. A$ j, I+ j9 e; a. V9 W+ N' _0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j+ u9 b; ]& ~0 e$ b5 j
    0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j
    ) Y( f- F4 j5 o. ^* Z0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j
    - D3 {( [( f  p  ?0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j8 d# `! X! ^+ z/ R: W
    0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j2 m1 r: N# V& o# N' ]
    >> help test/ \* G* L( T( g3 C
    本程序用于调试mx______函数.
    1 g2 R7 X' X8 |" m! [. @7 w7 c
    ) l3 B. K2 x  T% l: _5 b$ h1 D2 f2 f, E- ^, P( b$ w
    本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html
    7 A( v! h' S$ H2 T7 C
    . [, ]* K2 c1 G2 l- A下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

    总评分: 体力 + 5   查看全部评分

    转播转播0 分享淘帖0 分享分享0 收藏收藏0 支持支持0 反对反对0 微信微信

    32

    主题

    50

    听众

    2993

    积分

  • TA的每日心情
    慵懒
    2024-7-11 11:07
  • 签到天数: 543 天

    [LV.9]以坛为家II

    社区QQ达人 邮箱绑定达人 发帖功臣 新人进步奖 风雨历程奖 最具活力勋章

    群组小草的客厅

    群组数学建模认证项目实训

    群组我们一定会赢

    群组哈尔滨工业大学建模团

    群组聊天

    回复

    使用道具 举报

    0

    主题

    5

    听众

    101

    积分

    升级  0.5%

  • TA的每日心情
    开心
    2014-4-20 15:49
  • 签到天数: 4 天

    [LV.2]偶尔看看I

    群组Matlab讨论组

    群组2011年第一期数学建模

    群组LINGO

    回复

    使用道具 举报

    0

    主题

    7

    听众

    272

    积分

    升级  86%

  • TA的每日心情
    开心
    2014-9-22 15:14
  • 签到天数: 55 天

    [LV.5]常住居民I

    回复

    使用道具 举报

    tequila33        

    0

    主题

    6

    听众

    78

    积分

    升级  76.84%

  • TA的每日心情
    奋斗
    2013-2-4 10:21
  • 签到天数: 8 天

    [LV.3]偶尔看看II

    自我介绍
    想试试、、
    回复

    使用道具 举报

    lieove 实名认证       

    4

    主题

    7

    听众

    122

    积分

    升级  11%

  • TA的每日心情
    无聊
    2014-6-11 18:56
  • 签到天数: 23 天

    [LV.4]偶尔看看III

    群组Matlab讨论组

    群组数学建模

    群组数学建模保研联盟

    群组第四届数学中国美赛实

    回复

    使用道具 举报

    2

    主题

    8

    听众

    84

    积分

    升级  83.16%

  • TA的每日心情

    2013-2-16 14:17
  • 签到天数: 9 天

    [LV.3]偶尔看看II

    自我介绍
    数模
    回复

    使用道具 举报

    墨羽飞        

    0

    主题

    6

    听众

    480

    积分

    升级  60%

  • TA的每日心情
    奋斗
    2015-8-6 10:29
  • 签到天数: 143 天

    [LV.7]常住居民III

    社区QQ达人 邮箱绑定达人

    群组第四届cumcm国赛实训

    回复

    使用道具 举报

    fjnanyuan        

    4

    主题

    9

    听众

    130

    积分

    升级  15%

  • TA的每日心情

    2013-5-10 08:19
  • 签到天数: 30 天

    [LV.5]常住居民I

    自我介绍
    我不恨数模
    回复

    使用道具 举报

    2

    主题

    6

    听众

    117

    积分

    升级  8.5%

  • TA的每日心情
    开心
    2013-9-18 23:25
  • 签到天数: 53 天

    [LV.5]常住居民I

    群组Matlab讨论组

    群组2013认证赛A题讨论群组

    群组数学建模

    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 注册地址

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

    关于我们| 联系我们| 诚征英才| 对外合作| 产品服务| QQ

    手机版|Archiver| |繁體中文 手机客户端  

    蒙公网安备 15010502000194号

    Powered by Discuz! X2.5   © 2001-2013 数学建模网-数学中国 ( 蒙ICP备14002410号-3 蒙BBS备-0002号 )     论坛法律顾问:王兆丰

    GMT+8, 2026-7-11 04:11 , Processed in 0.934288 second(s), 112 queries .

    回顶部