QQ登录

只需要一步,快速开始

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

    " a( d' B6 ~% u! V: M$ ?Matlab调用c程序
    3 Q. v+ Z, {# p9 b文章来源:不详 作者:佚名
    ; L2 g; ^# B) f8 D! t7 c. O" m# W3 N  F/ H2 P' g) ^( @
    --------------------------------------------------------------------------------( q$ V- b2 _/ a5 u* R) C

    , f! h4 O. ?' n' I: L' A该文章讲述了Matlab调用c程序.8 V5 K6 |9 R9 `- {* @5 }
    $ k& [3 d# `: m% P
    方法:
    % {, o  V3 o, ?1 C1 Z第一步:要先在matlab中安装c程序编译器,步骤如下:
    ' v) F) }: `" k, u键入命令:mex -setup
    % p4 C, u" l! e0 E: _. n$ @! F+ ]* H选择c/c++编译器;
    - t) c, V7 r* Y. I- \' ^* H9 K选择c/c++编译器版本;
    & U9 E0 D5 z/ V$ H8 g确认。) T2 u/ \  _0 `  c0 o
    第二步:键入:mex *.c0 L" S! Q  [& w- g
    : L! @4 r8 T& H
    *********************************************************************************************************************************************1 s5 ]$ c" R1 ~- c  \6 d) y* z

    & Q: v  x' y6 H) X) V2 y实例介绍:【转】
    ) ~2 f3 m6 @0 ^+ I7 i* S$ e' N) _
    如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
    / Q2 L! n$ D7 I  d( C) rdouble add(double x, double y) {* ^; C2 R$ Q4 v- ^- ?! B
     return x + y;
    & P: e% z! x! g6 A7 f}
    & T/ x( Y6 y& s+ F; G: |) l, ?现在我想要在Matlab中使用它,比如输入:6 z+ J$ I6 n& I
    >> a = add(1.1, 2.2)
    1 _% |* w4 |" c" M+ s5 w1 k3 m! w0 ~3.30005 p1 v& G& g. e2 ^% @
    要得出以上的结果,那应该怎样做呢?
    % u0 m! p% c, b- A- p解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
      S5 z$ ~+ K8 x/ S可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
    - P# A+ o/ T4 C: g所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
    6 H: T# U, C1 p, ^0 O比如该C文件已写好,名为add.c。那么在Matlab中,输入:& i" ^* G. s7 Z; u
    >> mex add.c
    ( Y% c- X- Q# ^3 I7 u! v就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。% [( {, u# Q. F2 c- D' x
    我们现在来说mexFunction怎样写。7 d# E. M6 i0 @, H8 v
    mexFunction的定义为:
    4 [. A1 X8 Z' k# ?- S7 B  R, [6 `, hvoid mexFunction(
    & ~7 B5 r8 c& g$ O" |- m     int nlhs,
    ( I" _) C5 y7 d- {* k" j     mxArray *plhs[],
    " J- s0 L. f( a: h  F     int nrhs,
    8 o$ o* K; H* m5 q     const mxArray *prhs[]) {4 h, j% d( L# P& H, i- ^% f* e7 S
      a: w( T; `, S& A( Q" U
    }" d% j8 g( m7 b" ^% L4 R) e; y
    可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:2 v+ e# Z) z- Q" d
    >> b = 1.1; c = 2.2;
    " \2 ~3 ^& |2 u& u; b>> a = add(b, c)
    - Z$ m" a- \' p3 ^% t; zmexFunction四个参数的意思为:! J6 F/ R8 p0 e
    nlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a7 p/ P3 G3 c6 [+ n* k& `
    nrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc/ r  e# {, t7 p$ }9 d5 z
    plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a
    4 \' T. c! j1 C4 Wprhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。" L8 @. B% f: Z
    因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。
    7 A) F$ K2 M# P  n3 Y7 S完整的add.c如下:
    $ p& q! m6 @/ c4 u; [// add.c) a* m! ^( p+ V, d3 W" X8 I  T, y/ {: V
    #include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
    : Q. e$ Y" p4 idouble add(double x, double y) {
    1 f* \4 h- Z" _. N return x + y;1 r- c) e9 W3 @1 Q& c7 s: E
    } // MEX文件接口函数
    # `* X5 D- m! u; d/ o, _! y4 Hvoid mexFunction(
    & U4 T  `9 M! u! w) u  l2 r; ] int nlhs,
    ! d4 G. Y- p) { mxArray *plhs[],
    & u6 g& I: |+ N; q0 z1 Q1 f int nrhs,
    # E( Q: p: z, k8 |" I9 U const mxArray *prhs[]) {+ |2 X! {8 b3 d3 K
     double *a;
    2 B5 m$ x; Y( C1 R double b, c;
    9 c% E3 i' P  \# a8 V plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);# Z+ Y$ e' g* P
     a = mxGetPr(plhs[0]);, ?- L$ z$ p* I) \8 q9 A
     b = *(mxGetPr(prhs[0]));: X0 r+ T( {: r9 G; G
     c = *(mxGetPr(prhs[1]));! g6 h# {, w* m, Z+ ^  l
     *a = add(b, c);
    ) s/ @' ~, r9 c$ i1 D( x, o}
    5 z* s! d  q/ i0 [6 v7 A; gmexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    ' k+ C% D( Q' j6 O: b: L>> output = add(1.1, 2.2);. r* F& K6 S* |* `* `. Q: J# J
    在未涉及具体的计算时,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便是已计算好的结果了。7 J6 X7 n3 C* D% [; m/ C* i
    上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
    ( |+ s# ]4 J  D. P' f/ m$ N" f$ Q实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保1 H0 t0 c4 A* f
    输入正确。如在add函数的例子中,用户输入char array便是一种错误了。( ?/ u6 C; g/ B
    从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
      ?9 s$ B& U$ L- [* w
    , u. L) z- J( ]4 }. b+ j*********************************************************************************************************************************************% \! S+ w1 `! }! }  x. c: f! `

    # c: |4 v4 t) ?# O* C" B& g1 Umex 的目的,
      }& \; d8 d4 P8 A* p" l& P, B8 D
    . d$ ~3 @1 \3 @1 ]1 R通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:. N% m  i, u# `$ c) J$ I8 a

    + ]- n& M) b# z1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.
    + o9 q" m1 K$ r0 ~; k; i3 b2 U5 P5 i/ s; P1 k
    2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.
    ' s6 r5 ~% [/ C0 v8 C
    4 Q4 z8 a0 \  s. |0 Y3、据称可以弥补Matlab硬件设备接口的薄弱环节.
    , ~& l; o8 p! a1 g, v9 T
    1 d9 A8 y* L* E今天写了第一个使用MEX.% e' e: i5 e7 \* }/ m' t

    5 e# c4 F+ H9 ?; s! p一个简单的对Matlab普通数值矩阵的操作.- h- b& @2 j9 F4 g
    : x. h, c5 W) t; S! E' |
    其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以& D. {0 Q7 |8 `+ F% F

    " W1 n  G4 T9 t  I- {5 @3 s& A一律用int代替.
    & e3 P# S7 `6 X( A' H" V& p& B5 ?9 q
    . I- A# O( M7 u2 ~0 s/ o9 Y- I8 E#include "mex.h"
    % T4 p+ x  @6 u6 K3 S#include <iostream>
    : ?1 l; J" m- a' g8 T* n" O' z9 ]3 d
    void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])4 v7 X8 j) `7 A0 o3 u( r
    {* T% M; m- _+ {/ h( K7 w
    ) W6 j6 A) H" Q2 O1 Z" K
    int i,j,k;% g1 S: x9 l3 {4 M
    int index;8 ^3 f+ p8 h5 ^; N0 k' |
    double* pr=NULL;0 O! l' |% H, h8 c# x) Z
    double* pi=NULL;- m2 G* F( {, U1 o$ s. C
    int M,N;
    3 R" a1 M5 g6 N; ^$ R7 `# ~! ^- z8 R/ fint ndim;& c+ m2 Y) ?2 v1 `) W0 v3 u
    int dims[2];
    & B: D0 V; d( w% h) l* ?1 M; Efor (i=0;i<nrhs;i++)
    $ X6 y- @" p: j$ ^4 [{
    6 P# S+ `/ Z8 v7 i6 V. p) d   if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
    % H* m, h2 I& X" J- A* c( a6 B/ V" _; ^   {
    9 l0 [" B" ^; v* m( @8 B' w    pr=mxGetPr(prhs);8 V0 F( Y9 c$ n0 i; g
        pi=mxGetPi(prhs);3 |( H' H$ q: e1 `! ?* @
        M=mxGetM(prhs);. h4 y" I& }7 e
        N=mxGetN(prhs);
    7 G+ G  C6 m7 o7 u* g" F' Q    ndim=mxGetNumberOfDimensions(prhs);( T. f1 y; v/ s/ T: K
    + b5 f7 j& a* X( L
        mexPrintf("变量%d:\n",i);" u3 O' F4 B6 R  p% g0 C! o6 L
        for (j=0;j<M;j++)9 M( w4 i2 s* D: D6 Y. O
        {# I( Z# ]# W. p) a  J) i
         dims[0]=j;
    8 E. h  {% h0 f4 H/ R/ o     for (k=0;k<N;k++)# [8 y, Y9 q( c5 a+ A' K
         {" f- }6 o4 a( e/ v, l
          dims[1]=k;
    8 X1 R5 u* Y3 l" _+ e1 E      index=mxCalcSingleSubscript(prhs,ndim,dims);
    $ }, I! w: u" m* K7 [, R- @0 F      if (pi==NULL)
    0 a  q- D$ v; n6 E" A- m0 x      {
    5 R! ]# {, [: c# o, P1 x       mexPrintf("%6.2f",pr[index]);
    , i! f0 @) f9 L+ \      }
    " n- h0 s+ j! P. f3 B- I      else{
    9 A& q6 f9 B- D  l       mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);# E4 K! a$ q9 t# Z3 ?
          }
    ! O; i, x$ F; t. G     }
      ]$ Y" i9 E6 W$ ~9 L2 _  X8 K# w     mexPrintf("\n");
    $ ]( b, x$ N. a( s5 C. [" A) c3 b5 S  s( o
        }4 {) Q9 W/ H$ q! m2 K* g
      ! k7 O! P2 J2 |( M
       }( N) n2 a! O1 y  y' ?+ i) x
       else{
    ! R- X# k1 S, \8 t    mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
    0 E& l% f4 K( O4 [4 N6 N}
    - \* i! |7 m. x5 v; S" m8 C' D- W$ c3 ]3 `5 Q
    7 G& ]) _, R* s! u- S5 X8 R
    }
    - u+ T( p- \& `. a2 R, P$ b# G# Z  `" L
    }0 V8 g& a. s! s/ i. I6 j' n

    5 I7 I% p0 y2 n% J4 y9 I* M( jResult:
    - D& s/ n+ E& s4 Z6 ]/ c8 a) p4 z" }
    >>mex test.cpp8 B5 K4 P0 B& C. |" O9 t
    >> test(a,b,c)
    - X$ w6 L5 f3 m, `+ E变量0:
    ; e9 Z9 `/ M7 g: V2 q0.35 0.62 0.83$ c3 b  m+ \, Q/ D4 G$ j6 e
    0.20 0.47 0.59
    3 _" \: p3 z% r# ^- e7 _/ E; u0.25 0.35 0.55
    * z' t6 j# m  c8 B. f变量1:+ G; c, c. z1 [' `7 A
    0.92 0.38 0.53 0.57
    8 w, m6 N( _% ^* O0.29 0.57 0.78 0.47  P4 b8 V" e- R) T. |4 |& M
    0.76 0.08 0.93 0.01# y- i) u3 w/ e& e7 ?
    0.75 0.05 0.13 0.34
    : d, u7 U+ E7 j3 m变量2:
    7 M( l9 e- l8 q$ w0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j
    6 }9 \) m, V$ v* x, C0 A0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j
    9 Y! ?5 G* w8 [. k! ]5 i% k0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j0 e6 c* {2 T. x
    0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j
    " _; u. W: N  T3 {3 S8 ?0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j8 @, D& s$ l6 j" ]9 Z: o# g+ n
    >> help test& N# G4 J0 u. _) R5 E4 h5 ]$ d$ }
    本程序用于调试mx______函数.8 j4 C  `! i! G6 X: h: u7 N

    8 [8 N/ n3 ?5 w2 u, B
    ( [# L, T7 L/ u& w- P3 g本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html
    , [* A8 [# t$ S' ]" s, u
    5 k6 U# A( Y( D- X8 H4 K. q4 d6 V下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

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

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

    32

    主题

    50

    听众

    2987

    积分

  • 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-4-13 01:03 , Processed in 2.003302 second(s), 115 queries .

    回顶部