QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4755|回复: 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

    : N2 @$ S( d0 q! z; N7 a: Q% c- j: NMatlab调用c程序2 |4 W" ]$ R& g# F# {
    文章来源:不详 作者:佚名
    3 j4 j7 y" ^! |- v$ F% x; _; Y. ^9 s' _* {
    --------------------------------------------------------------------------------
    2 B: ]) b7 {. h# o7 R* ^4 [; p
    该文章讲述了Matlab调用c程序.. t% ^) x" A; D8 _: H" ]; H
    ( W! Y, }3 f0 ^9 x% q1 u
    方法:
      t; [5 h2 D" R; R& i' m$ M第一步:要先在matlab中安装c程序编译器,步骤如下:; r( W' {6 |6 s
    键入命令:mex -setup;" l: b; V- E2 P" ?6 ^4 n  ^- v$ O( P
    选择c/c++编译器;) Z% d2 X0 g% I; U! H
    选择c/c++编译器版本;+ \! y& d, Z$ C: A) z& h
    确认。
    2 H& g% j  [; _) c7 u( T: e第二步:键入:mex *.c
    * M2 b, l* D( w) Z, o$ {/ U% P0 o3 ^6 d9 k
    *********************************************************************************************************************************************
    ( K4 V- D6 w7 m: e: d( ^1 M5 u# ]: `- @& Y  w
    实例介绍:【转】1 d" c- F9 @" F5 W/ t

    4 F; ^9 c: }4 C7 Y% L如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:# X$ d" p$ }: O1 X5 c! W% ^
    double add(double x, double y) {0 E* H0 I+ L' {3 S# R4 f  C# W
     return x + y;
    # U# U  i* [2 z- K1 B}
    8 R3 t; M& _% _% a6 _现在我想要在Matlab中使用它,比如输入:0 y: t% s4 H" n3 d
    >> a = add(1.1, 2.2)
    2 b) n: O& X+ E, R) }5 g# X3.3000* B) O5 h1 ?$ R- N0 z/ L
    要得出以上的结果,那应该怎样做呢?2 @' ]: p' V; S8 P' ]
    解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。% y1 {8 ?& M! g0 l! A
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。% `& a5 o/ _1 A4 M5 S
    所以现在我们要写一个包含add和mexFunction的C文件,Matlab调用函数,把函数中的自变量(如上例中的1.1和2.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
    ; K2 c; |* k+ x5 Q比如该C文件已写好,名为add.c。那么在Matlab中,输入:, T# ~) x# n% i; s4 R3 g8 X
    >> mex add.c" Q! H% W9 C5 H0 D) N# x8 F1 X0 M! S
    就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
    6 C7 Z$ {) y( p8 f1 P3 W4 x我们现在来说mexFunction怎样写。
    8 O  Z2 ?# Z2 [* h7 pmexFunction的定义为:
    " k" T: G: ~' |2 ?1 z1 Svoid mexFunction(
    8 ^* ~8 e4 _+ V' @5 F5 A     int nlhs,, G+ P4 k$ c, }) O
         mxArray *plhs[],- [$ h( Q6 P9 S( ^. X7 }( F7 l
         int nrhs,
    . |% R% u  k) U  i) P; B8 \     const mxArray *prhs[]) {
    ; f: ]5 X' u4 Z7 Y4 h
    + f% F: Z" d! j8 i8 _$ g6 r}
    4 B" u9 V, \" r1 {1 o. j; L" m可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
    # Y5 v9 f* \5 v* ^6 }>> b = 1.1; c = 2.2;
    " ]' ^) l' u& Z>> a = add(b, c)
    # C' h- z0 E8 J) ?( ~" TmexFunction四个参数的意思为:
    ; R/ T4 l3 t9 e- [5 Cnlhs = 1,说明调用语句左手面(lhs-left hand side)有一个变量,即a。
      g0 |; }1 }( _3 Y) inrhs = 2,说明调用语句右手面(rhs-right hand side)有两个自变量,即b和c。
    . n- J3 ]3 }# v0 `2 Q% y0 B. rplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a。, @* P/ w9 X! [- Z! u
    prhs和plhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了b,prhs[1]指向了c。要注意prhs是const的指针数组,即不能改变其指向内容。
    . l( X3 z& ?6 K$ p3 v  j因为Matlab最基本的单元为array,无论是什么类型也好,如有double array、 cell array、 struct array……所以a,b,c都是array,b = 1.1便是一个1x1的double array。而在C语言中,Matlab的array使用mxArray类型来表示。所以就不难明白为什么plhs和prhs都是指向mxArray类型的指针数组。
    2 Y- A6 E& F9 [  a5 ?. i完整的add.c如下:
    # M- H" M4 P3 l* f: O* y2 O// add.c
    8 l2 a& T, R3 |2 w! e#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数3 G/ `+ o( Z4 D) C4 ~* z5 c1 i
    double add(double x, double y) {
    0 l' \9 F( H: `! i return x + y;
    % s* d! [7 y# q. p# H! g} // MEX文件接口函数
    4 F: W" Z. g5 g( R# p' M- tvoid mexFunction(% z  d5 ^! j' b& g
     int nlhs,
    9 O1 ]3 c( c& f$ W* ]2 V mxArray *plhs[],! f7 N1 ?  r# l* y
     int nrhs,2 g: h# T; E0 l6 ~# d+ C0 q' ]( P
     const mxArray *prhs[]) {. D8 K1 x# |: q# n
     double *a;3 i+ e+ e6 i' \( g$ J4 v) m
     double b, c;
    2 ]" `, J3 e) A8 k& C plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);0 N2 f, Y( D/ K. q
     a = mxGetPr(plhs[0]);
    6 r/ m4 m7 i4 J  }( d" |. v b = *(mxGetPr(prhs[0]));- X# H0 T# E$ ~' m: @& R  \
     c = *(mxGetPr(prhs[1]));7 i" d. ^; k2 e  s' I  O; @
     *a = add(b, c);5 F+ \7 y1 g0 b% w8 A$ L
    } ) A! R6 d) R" `" w) _6 i3 a! i. P
    mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    5 [$ Q0 B  m$ s) D" o>> output = add(1.1, 2.2);
    4 r7 r  U9 Y  S2 }9 v3 W: x在未涉及具体的计算时,output的值是未知的,是未赋值的。所以在具体的程序中,我们建立一个1x1的实double矩阵(使用mxCreateDoubleMatrix函数,其返回指向刚建立的mxArray的指针),然后令plhs[0]指向它。接着令指针a指向plhs[0]所指向的mxArray的第一个元素(使用mxGetPr函数,返回指向mxArray的首元素的指针)。同样地,我们把prhs[0]和prhs[1]所指向的元素(即1.1和2.2)取出来赋给b和c。于是我们可以把b和c作自变量传给函数add,得出给果赋给指针a所指向的mxArray中的元素。因为a是指向plhs[0]所指向的mxArray的元素,所以最后作输出时,plhs[0]所指向的mxArray赋值给output,则output便是已计算好的结果了。" P2 Z4 A' D" K: q! N  M0 I
    上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
    3 z. N) G- ]) r3 Z% r实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保" C4 j1 {7 u5 {) Y( J* l" q$ }
    输入正确。如在add函数的例子中,用户输入char array便是一种错误了。/ L9 {4 L  C* N" ~/ w  @6 G/ h6 p/ n
    从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
    ( ]# @/ h) m/ e: Z3 ?, a+ q
    0 w- z3 k' @* m/ [*********************************************************************************************************************************************
    # o1 M; c) J3 W& f0 ]; l. Z/ u( K; {% d5 c) |$ _$ U* N) K
    mex 的目的,% [' M( V! [! v6 p" H

    % n' e& S# l. ?% G  X, k$ T通过C/C++语言编写代码,在Matlab中将其编译成mex文件主要可以做以下几方面的事情:3 R9 q& l; m  k
    0 V# N, L- R, T
    1、加快程序的执行速度. Matlab在for上如老牛拉车的速度确实让人抓狂.6 [1 B4 }  W7 m

    ) L6 U6 ^( o7 f2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,用Matlab观察其中间结果十分方便.. E" a+ _. o8 Q/ A8 K: j; C
    ) |7 o* I# Z* Z7 O- `- b6 k
    3、据称可以弥补Matlab硬件设备接口的薄弱环节.! q; X( d9 v7 C0 K9 M

    . {" Q4 [- Q% J今天写了第一个使用MEX.
    9 J- I  N# y$ ?$ s5 e9 ?8 d; n1 J% F  [1 t: p9 h5 F: k/ |+ ~
    一个简单的对Matlab普通数值矩阵的操作.
    7 l8 p- X4 ~; f& X7 }. j' y; h
    4 r% c5 d. t) W7 V, i& G- L其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t在32位系统上其实本质上就是int,所以
    ' P, ?7 j; L5 D4 \$ |  g; L, h7 w- e6 f! t7 ?. ]
    一律用int代替.7 k! c: o. W, z

    / m8 ?5 _# r2 y) o#include "mex.h"
    % t/ Q  [& E3 V, a5 e#include <iostream>
    ! n, e' B! _) z/ k% I/ k# c, ~, j% `  N/ X! j
    void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
    2 V( s) j- V- r+ x1 l/ v8 F{" k8 v, P" |3 S- f! [! m7 n+ I

    5 R0 d( y/ f; q4 U( C! p/ Lint i,j,k;! G( u# q0 I1 U. l$ p# Z
    int index;
    " I; T* \  v" Kdouble* pr=NULL;
    % Q+ ~5 A+ y- d8 n" @3 V+ z: @double* pi=NULL;
    . l0 S# R. @) wint M,N;4 [4 q* |1 N* \% x; c+ a- K
    int ndim;  B9 g4 X/ D! b: w3 Q, v5 l
    int dims[2];2 K# ~, p, z% f  D, L
    for (i=0;i<nrhs;i++)
    1 I0 Q# C: n, ]  G4 E8 ^{* p1 B, m" v- g" V
       if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
    0 J2 F+ G" }( M2 L+ c% o   {  K( j1 c' X# x$ C
        pr=mxGetPr(prhs);$ x* w% f9 a  B2 j' ^$ P  d
        pi=mxGetPi(prhs);
    8 q& l& b% E- V' W) t' X    M=mxGetM(prhs);
    3 X0 d/ [7 K8 L    N=mxGetN(prhs);
    * |7 H) O9 K( w    ndim=mxGetNumberOfDimensions(prhs);0 W- [$ ]' ~+ w
    8 N# p+ Q- `. B
        mexPrintf("变量%d:\n",i);8 W1 O& Y4 D  D2 Z# Q6 e
        for (j=0;j<M;j++)* e9 F/ Z6 {6 K3 V, K1 o6 g
        {
    & \3 U4 P6 _! p0 _9 t* A     dims[0]=j;- _! _7 `6 N, z3 h% Y! ]6 ]  o
         for (k=0;k<N;k++)
    3 h2 a; B) [- b) [' r& I     {- w* f0 t! w: _
          dims[1]=k;
    4 B) \  R) U; v& N# W  U0 Q      index=mxCalcSingleSubscript(prhs,ndim,dims);
    * ?4 i0 ]( Q; {: _: ?& x      if (pi==NULL)1 H* k3 b& m" D: G3 C; R9 D! i; B
          {" l; _1 E& j- l$ p# V( l( p
           mexPrintf("%6.2f",pr[index]);
    ) l1 B- J$ B* v3 z      }, b1 a  b. j/ {* Y- [- x
          else{, M8 T+ Q* O' g  I
           mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);. l, w& [* d4 A0 }' s6 a! j
          }
    , Z, W/ i6 h) f6 ?0 ]     }. O* K- B( m9 \, ~- P
         mexPrintf("\n");
    " z4 J8 q2 Y: n; D' O+ l4 X3 e* |: v; R
        }/ p1 `$ Z. U5 L) V" _. G$ M
      
      D* D, T- j# Z; t/ t1 ?+ k8 m   }
    ' i/ Y. T8 b  j8 x- a3 u   else{3 l( D# m! m/ A) m2 ~/ Q. h
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
    $ x+ @1 N! a- R}
    + `* t+ ^+ V+ _7 f
    7 `' b! T2 r7 ~( R+ }5 A1 Z5 B9 e% m( \5 B7 r4 ]
    }
    ; n$ G4 M' ]! w) m8 V0 E/ n4 ]1 q  t& `
    - p) n6 `3 ]% K% s) W6 R' n}
      f: d1 D( u3 V- \0 f9 T. E- y% j3 {( `) ^9 a+ \% n6 o' }
    Result:
    6 C* ~& X8 `9 \; o* f' b/ ?
    ; O# {2 Q3 y9 }& Q2 _) j>>mex test.cpp  t' q( ^1 c6 C# s
    >> test(a,b,c)5 F1 A) L6 y" C: ~
    变量0:3 ], [' {+ v5 M. V& P6 J
    0.35 0.62 0.83
    7 J8 g" p  D/ Y3 u% ~0.20 0.47 0.59: Q5 o" v# N8 ]9 S  h4 ]0 t; M0 x
    0.25 0.35 0.55
    / ?6 _! m5 u' d, a' U变量1:5 V+ ]' V$ F2 n; c; p
    0.92 0.38 0.53 0.57
    # ^9 O. E# n8 D0.29 0.57 0.78 0.47
    ( ~4 a, ~8 f2 N0.76 0.08 0.93 0.01
    7 a4 j& v! @9 I) Q0.75 0.05 0.13 0.34" M8 O/ H2 f1 }( B4 D- K# k' v1 j8 J
    变量2:
    6 W. ~( s2 c, r  }9 e4 z0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j
    7 |0 z' _/ H9 C0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j
    # C, s4 \0 i" C# o0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j
    , s: b- q4 D. _; n# S0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j
    0 ^# a" m0 Y4 n2 H; q0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j: f. f" B' |0 U, t2 s  b" _8 R
    >> help test$ M' ]- K3 w. P: k0 [8 f
    本程序用于调试mx______函数.' |- c. E: x5 m! B- U/ a9 D
    6 P& d& l8 w- N. e& G+ g

    0 W0 `/ Q7 e, c5 Z本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接):http://www.zdh1909.com/html/matlab/14744.html. J8 _( B, |) p+ ?* }' R. q1 T
    , `* F6 ?# r$ v. L1 e9 @  D: I
    下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

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

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

    32

    主题

    50

    听众

    3018

    积分

  • 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-10-27 14:49 , Processed in 1.903327 second(s), 115 queries .

    回顶部