QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4335|回复: 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 K; }$ a) n9 BMatlab调用c程序5 i" ^1 v/ z) Q3 w' b! y; A
    文章来源:不详 作者:佚名
    " Y9 e0 U) ]' u4 V  R( r  t  ]! K6 T9 D+ O9 u
    --------------------------------------------------------------------------------( d: c4 I4 J: G+ B, j
    # N: G% ^, K* ~; I$ c: O
    该文章讲述了Matlab调用c程序.* n" c# w( }( W/ c3 t7 E% V8 w

    ; e# k/ Q. b* x- C9 W) p2 Y方法:! c, ~* h! o; v% {
    第一步:要先在matlab中安装c程序编译器,步骤如下:0 {- [7 q( v+ U. _- u8 P5 x& r
    键入命令:mex -setup
    ( E& ]% T: |0 t: Q0 t4 D选择c/c++编译器;
    , k% s% O" ]( d, M3 V选择c/c++编译器版本;
    ' @* e, i- U/ _" t' ?确认。
    1 j+ F" f5 M( o/ V  u" O第二步:键入:mex *.c
    / x7 i' W7 p, E. W0 y3 j! L- H
    ( H; I  ]0 J$ b! g; [0 I*********************************************************************************************************************************************; F) [: m. w$ R
    + ^7 @3 X- j- p( s( [
    实例介绍:【转】' M* ~3 e. e# Q0 G

    1 d, C, x5 M- [9 d. O  d0 Q如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
    . ]8 J3 h/ C4 b" V6 b' ?double add(double x, double y) {0 d8 ^$ y8 @/ |# N& }
     return x + y;
    ! t! i1 t! s" P/ Q- f. m- X. Q  e( Z8 X2 }$ l}4 t; f; h" f# P( a4 ~  x
    现在我想要在Matlab中使用它,比如输入:
    : M$ V+ f, O0 J( `>> a = add(1.1, 2.2)
    " n& X$ G9 G+ r  \5 L% F  x; x3.3000, l# F2 W! v0 G: Y  J& a
    要得出以上的结果,那应该怎样做呢?
      v; [3 Y8 Z$ R1 y; X" \解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。  U6 ^( j0 `  _
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。: r/ X5 H1 ?* s1 g% ~
    所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。: x$ X$ p0 b; S8 I3 Q) Q
    比如该C文件已写好,名为add.c。那么在Matlab中,输入:/ W: \, T7 n8 M$ k
    >> mex add.c# k' t, G7 s: P$ X9 j
    就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。/ d4 e2 h  i1 d3 i# j
    我们现在来说mexFunction怎样写。. ]6 [3 q; X. ?8 ~4 r4 L9 Y
    mexFunction的定义为:! s  P- t# v4 x, g3 @( m% H
    void mexFunction() ?& W3 V" }7 l  m+ c4 W
         int nlhs,/ _0 A' o6 s1 m% B/ N5 s
         mxArray *plhs[],8 j# w4 k+ l! t& a/ |
         int nrhs,  A* D' A2 x' [! L
         const mxArray *prhs[]) {" V. p4 j/ v7 z- D6 e: F! N

    0 C2 [" ]: o9 v9 G}
    ) Y. H; R( w' I2 Q可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:& f0 V7 q( x& E
    >> b = 1.1; c = 2.2;% F, M- c3 c. Z: H8 X9 P( U9 U% R
    >> a = add(b, c)
    - |. t3 r0 k" R/ k4 J& ]mexFunction四个参数的意思为:/ k  T( |+ o& P
    nlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a+ K4 |2 k, \5 D$ t5 x
    nrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc
    ( j( r, c) Z+ w' Y, {4 q0 Cplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a
    " w) g- |! [6 E$ lprhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。
    ) M8 C/ ], j+ R因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。! `% t' ^& P* e6 k0 O0 y! \
    完整的add.c如下:/ E5 U) \# l& q4 W' G) y% s
    // add.c
    + N8 ~1 F5 A7 Q1 _# Z8 y#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
    ( g+ [' s5 e: W  Fdouble add(double x, double y) {
    / j+ M: x3 p/ M, _* Y- H! k- c9 x  r return x + y;9 P. l$ u, o* M4 w
    } // MEX文件接口函数% N2 I' a% o) ]. s) i# y: s" A
    void mexFunction(: p. s9 W% X: K9 q4 M: Z8 b
     int nlhs,
    . D, N( i3 h" Y* \ mxArray *plhs[],# ^; l  B1 M. t7 _
     int nrhs,' w3 U) Z" n1 ~( o, |2 f: P
     const mxArray *prhs[]) {! ]$ q/ W: u# \% k7 Z
     double *a;
    6 b' M/ I; D4 U# L% M! } double b, c;- Z# L4 F. h: O3 k, L, i
     plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    - a7 C+ m# A% k a = mxGetPr(plhs[0]);
    + c3 I5 p& ^/ L* O' p* i b = *(mxGetPr(prhs[0]));- r9 p- \: D4 g; v- \
     c = *(mxGetPr(prhs[1]));6 X) z! d6 C* R9 j( t$ O
     *a = add(b, c);+ _- z) t$ o+ |9 c2 F8 Q: M
    }
    0 F# ?# k: M7 ^+ R) |mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    8 m& g# W5 F# e>> output = add(1.1, 2.2);& @! d' Z2 y! ?+ O! t% h
    在未涉及具体的计算时,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便是已计算好的结果了。2 R" w3 w& s! V* Z' Q6 e# `" M
    上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。. {% J% T. ~+ g1 t# |- \
    实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
    / p& V  s- e( S4 w; ?8 {输入正确。如在add函数的例子中,用户输入char array便是一种错误了。9 J8 E4 M# L) d& N: I6 E
    从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。1 ?; C" D0 \, w  _. M" z
    ) {* k6 ]  C$ L
    *********************************************************************************************************************************************8 i: R7 W1 N6 Q# ^

    6 [: o, A; G  `7 mmex 的目的,, d' D* r$ y  J4 W
    ( Q8 O9 |. L7 V2 Y  Y' U
    通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:  i) e: F: m; ]' S
    & N' M* h* u" g5 k
    1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.; l4 H; x( r9 J" ^
    . j: h, L, e' [, C& g
    2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.
    7 O6 o* Q$ M2 V$ q. X  Y8 `3 g# o- a$ D
    3、据称可以弥补Matlab硬件设备接口的薄弱环节.
    ' `; L' M8 ?, p; S7 u$ T! Q1 k* D" I- K
    今天写了第一个使用MEX.) f8 d5 [* d$ K% [5 [( v& {8 Z

    ; f4 N; n8 d8 T7 j一个简单的对Matlab普通数值矩阵的操作.
    / ]/ L" A+ s( B$ z5 f, G, ?0 m; U: K# i; [
    其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以
    / K' U* u+ N1 V, o* \* J
    , t3 Q' g9 r3 e9 c1 J+ c8 e一律用int代替.
    ' m, u& d' I/ X0 m2 x: |0 l8 _( l0 G: z/ j" M
    #include "mex.h"0 v, W  Y/ u( P1 ?3 A
    #include <iostream>1 r4 G0 L& a" \! U* W

    9 r* n0 s! Q- Gvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
    9 Q; [2 W+ \: w8 I{+ K2 ^9 \9 g' u6 T

    . n* y3 I1 H& N- f! Q- F7 K' g' rint i,j,k;
    # {5 v; X, t8 wint index;0 k5 ]6 u4 J3 O8 y/ f
    double* pr=NULL;6 e. I* u* a: O: Z1 Y
    double* pi=NULL;
    , G( K# ^* a+ o7 oint M,N;' f( ^0 n5 y0 G& M
    int ndim;$ d: h; |% u1 y: T2 @
    int dims[2];4 s1 X; U" Q8 f: y
    for (i=0;i<nrhs;i++)0 b4 N" W4 K- g% J5 K
    {1 Y' R$ }0 N. h+ D+ o+ ^5 k
       if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))# Y3 a3 D0 g0 ~5 K2 J4 u0 O$ Z
       {
    6 e, l4 g7 A' n3 w% V) ]7 @" n    pr=mxGetPr(prhs);4 b, U' h* v1 u5 T6 G! [3 G
        pi=mxGetPi(prhs);
    % Y4 |5 y" ~8 m/ ^) Q+ v, f2 _    M=mxGetM(prhs);  z* N* k4 |; v8 a
        N=mxGetN(prhs);
    4 z# v! B$ {) e8 S" U    ndim=mxGetNumberOfDimensions(prhs);
    . ]' c+ w& `5 w3 c! O
    * L; G1 J6 h2 |/ H0 y% t7 [4 s# E5 N    mexPrintf("变量%d:\n",i);
    ! O2 B& d  H  p5 j/ o2 q    for (j=0;j<M;j++)  J9 N9 H( x! x" I
        {
    2 P& ?) y+ ^+ x6 T, P7 i5 t) E     dims[0]=j;4 Q5 q2 W8 Q* C% W
         for (k=0;k<N;k++)
    0 Y% y8 L8 E) ?     {
    ! L" p3 `0 b2 G3 W; J      dims[1]=k;* l% q1 i$ Y- e# E. D  L! d9 W
          index=mxCalcSingleSubscript(prhs,ndim,dims);
    & A1 j* n& Y6 O- P      if (pi==NULL)
    7 F7 ]* w$ w# V6 u5 b: b* R      {4 y; s) Y8 o" s5 E
           mexPrintf("%6.2f",pr[index]);
    ) w9 Z6 D( w# p# [      }
    5 \' B5 w+ x4 W      else{
    2 c9 S7 @" F! Y       mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
    # S! g0 c! z3 T# {4 v      }" ?3 v: t5 f5 e. H  m
         }
    - m" |) y# V$ p* K* R     mexPrintf("\n");4 t% B+ {0 h8 q& Q
    2 e" x+ f  i% m5 E' D5 Y9 U
        }
    # c% c; |& A) O  * Z5 Z. a6 h7 h8 Y
       }
    ) j; @! p4 R8 G   else{/ I( A# J! m# B( z. q( G. O8 d
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);7 o) e" \8 F; z
    }
    6 _1 V# }. a) i1 h7 E
    ; |2 t3 }5 p& ?. \0 _
    0 C4 N8 C, C1 g+ O( C- u! [* g}: U" P: \$ B+ X; N, h( y" }, X

    . ^5 ]6 O+ f  E8 M: J0 Y}( u$ u' Q: @! j8 d8 n6 R6 ]/ o

    ! n  K. b- v& G4 F. ?Result:
    + [* u8 x; G9 L; w% ^
    8 V( ^. M  ~/ T  d( Z' z>>mex test.cpp$ m; p( P2 r: C1 \" }2 a9 a
    >> test(a,b,c)
    - R& b+ m9 ~, Q* A. p5 m8 F变量0:
    5 g% }# `# I/ g  Y* L0.35 0.62 0.83$ G* I/ t4 K3 j4 Q9 N! }
    0.20 0.47 0.59
    ( m) O$ w' d- H3 J- O/ U2 B& x# f6 o0.25 0.35 0.556 U1 u% S1 I: [. \8 C6 i& M* R/ E
    变量1:
    9 g, m# O, j0 }, u: h# Q0.92 0.38 0.53 0.57
    & l& U) _4 S- C/ S% M8 \% _9 ?0.29 0.57 0.78 0.472 M( ?0 Y! D6 K( Y1 F& g
    0.76 0.08 0.93 0.010 f3 w1 _5 `% E& {) t
    0.75 0.05 0.13 0.34. e/ L  [& r. V/ r
    变量2:
    - G0 H1 `+ ^4 J1 M0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j: L  n% w: Y0 O; p# C8 r
    0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j
    * K2 u* b8 \" d4 L0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j, h, k- D! i: {4 g! y9 p
    0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j
    / D( C( S+ Y$ p. a2 T0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j
    + o% F3 [) I! t>> help test+ y0 w  g$ X+ H0 ?6 a7 U
    本程序用于调试mx______函数.1 Q2 D. o/ [$ j

    8 u, _. c, m1 M# |% c, Q7 c  q# F7 g( v8 m
    本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html
    ) E. z6 c& R9 \( \  P' _6 U  e. y
    下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

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

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

    15

    主题

    10

    听众

    799

    积分

    升级  49.75%

  • TA的每日心情
    开心
    2015-7-17 20:50
  • 签到天数: 68 天

    [LV.6]常住居民II

    自我介绍
    我是一名大二学生。

    群组2013年国赛赛前培训

    回复

    使用道具 举报

    2

    主题

    6

    听众

    117

    积分

    升级  8.5%

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

    [LV.5]常住居民I

    群组Matlab讨论组

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

    群组数学建模

    回复

    使用道具 举报

    fjnanyuan        

    4

    主题

    9

    听众

    130

    积分

    升级  15%

  • TA的每日心情

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

    [LV.5]常住居民I

    自我介绍
    我不恨数模
    回复

    使用道具 举报

    墨羽飞        

    0

    主题

    6

    听众

    480

    积分

    升级  60%

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

    [LV.7]常住居民III

    社区QQ达人 邮箱绑定达人

    群组第四届cumcm国赛实训

    回复

    使用道具 举报

    2

    主题

    8

    听众

    84

    积分

    升级  83.16%

  • TA的每日心情

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

    [LV.3]偶尔看看II

    自我介绍
    数模
    回复

    使用道具 举报

    lieove 实名认证       

    4

    主题

    7

    听众

    122

    积分

    升级  11%

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

    [LV.4]偶尔看看III

    群组Matlab讨论组

    群组数学建模

    群组数学建模保研联盟

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

    回复

    使用道具 举报

    tequila33        

    0

    主题

    6

    听众

    78

    积分

    升级  76.84%

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

    [LV.3]偶尔看看II

    自我介绍
    想试试、、
    回复

    使用道具 举报

    0

    主题

    7

    听众

    272

    积分

    升级  86%

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

    [LV.5]常住居民I

    回复

    使用道具 举报

    0

    主题

    5

    听众

    101

    积分

    升级  0.5%

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

    [LV.2]偶尔看看I

    群组Matlab讨论组

    群组2011年第一期数学建模

    群组LINGO

    回复

    使用道具 举报

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

    qq
    收缩
    • 电话咨询

    • 04714969085
    fastpost

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

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

    蒙公网安备 15010502000194号

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

    GMT+8, 2026-4-14 10:55 , Processed in 0.539997 second(s), 116 queries .

    回顶部