QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4336|回复: 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
    $ G2 O3 d5 T, c5 m7 C' z' s! \0 ^
    Matlab调用c程序) C: F: Z0 @7 b% ?6 Z. o
    文章来源:不详 作者:佚名 $ J: }; J# W( w5 M1 Y; v$ q

    ' R. ?! Y: @! ~" s7 ^--------------------------------------------------------------------------------3 D, {! F) x% k: P" u

    ) b* E6 Q4 N, z该文章讲述了Matlab调用c程序.
    * x% G- i4 W2 ~) j1 L& P
    ' H0 p  j9 z3 A! }$ t, t方法:1 y1 R/ ^8 n- A; p1 a! C
    第一步:要先在matlab中安装c程序编译器,步骤如下:
    2 S2 G" X% N7 J( T' ?, k0 H- o6 R  {键入命令:mex -setup
    ' V& w4 q1 n1 `; P0 m: j9 c. l" c) I: w8 z选择c/c++编译器;
    6 y' r# Q* Z0 w6 [' P- ]# ]' O; s选择c/c++编译器版本;/ |) g! o: G) ~! e9 R
    确认。
    . D  |* [+ o7 h第二步:键入:mex *.c, }6 f  T, C+ b9 ?" ?# e1 m$ _$ ~
    ! T* f7 p$ W% y" F( l4 x
    *********************************************************************************************************************************************- c. ]# v3 {9 V- P* f

    - b& m1 x; y% m* W实例介绍:【转】9 x: R6 J$ C& E. q

    2 e& ]; N4 \, j: }如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:: y, ^1 g" l! n  d4 m5 e8 I) U- n
    double add(double x, double y) {7 `3 w# U1 T) j
     return x + y;
    5 ?: \' t% C7 l7 R8 V}& W. f9 q# E/ H( S6 ~, {4 q; a* }# K
    现在我想要在Matlab中使用它,比如输入:
    7 |! x+ z9 C' J: X" u>> a = add(1.1, 2.2)' o0 b( r7 C: b
    3.3000
    8 Y1 U0 k& Y" w, i6 f8 P' v要得出以上的结果,那应该怎样做呢?
    0 `9 t) y+ j8 v; H6 R: k解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。
    $ }2 V  x8 K6 h可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。4 G! k. |% q: s+ ]0 x
    所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
    & ]$ s: q! T. X. D比如该C文件已写好,名为add.c。那么在Matlab中,输入:
    8 h. @9 n1 Y& |>> mex add.c# }4 d# t9 G* |4 S9 A, L, B
    就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。+ ]/ A0 g3 A9 ~
    我们现在来说mexFunction怎样写。* ]2 z4 j( p5 D3 g
    mexFunction的定义为:2 g4 R$ d1 d8 F) e7 y" L% _
    void mexFunction(
    $ g5 h9 T9 R2 _; u8 m1 |6 D* Q1 m     int nlhs,
    3 d9 \+ Q0 G, W5 E6 U% q+ }     mxArray *plhs[],& d+ j% B( ]  j. o; o
         int nrhs,
    7 e! ]+ ~7 {! r% |6 N     const mxArray *prhs[]) {
    " e' s$ ?4 h& U) p4 o/ f  E1 E0 x8 M6 Y$ f$ }# x
    }
    : R# x$ s& z+ u% P7 E1 X, K可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:$ U0 k. m' b* I& J6 M
    >> b = 1.1; c = 2.2;$ |7 p# L3 C8 I1 L
    >> a = add(b, c)3 y) D+ A! |3 t' p
    mexFunction四个参数的意思为:/ ^0 [+ Y6 c" R2 y, i3 e
    nlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a
    5 H: [& W; M  l" y5 D& ~nrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc
    / |8 e" m( N4 H6 }2 y. Vplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a
    - t; t; G: K& V  ]  c! ~prhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。, O/ z' t8 N* C: Q7 m
    因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。
    + _* R3 Q* [& b& T# p完整的add.c如下:
    , A4 |- p+ M( j7 H) I. [" g// add.c
    2 u. L$ ^6 U5 T. p' N5 d& T#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数
    - U8 U9 {  M  {1 Y" kdouble add(double x, double y) {3 |! ?5 O1 ~% m2 L7 ]+ {
     return x + y;* M$ K1 k9 G+ O2 r+ {  w+ E7 t
    } // MEX文件接口函数2 t: Z; F3 a3 R4 V( H& ^
    void mexFunction(
    # I9 `# i, Q8 U) T int nlhs,( F6 c( x+ `7 E8 Y
     mxArray *plhs[],: @& d0 n. h- b/ b. W: c6 E
     int nrhs,. _- G1 G2 N. Y5 {7 j
     const mxArray *prhs[]) {) m, b# [% D7 |; y
     double *a;- @# P! m! c. r+ ^! P) L. b
     double b, c;6 K' _1 i. g& J9 @" T  g
     plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);/ ~6 }: u" B9 P' |
     a = mxGetPr(plhs[0]);
    ( L( }6 v3 s# P  k7 Y: m b = *(mxGetPr(prhs[0]));% \* z) m- A1 }% Z
     c = *(mxGetPr(prhs[1]));/ s" s, a5 X" B4 a2 V
     *a = add(b, c);
    ; p. q, E& y  S8 P# k% F}
    ' E6 D/ E& F/ j4 n8 ?mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    % W- v  Z$ c/ q5 w: m0 r! ~  ?$ }>> output = add(1.1, 2.2);( U1 N$ ^: X2 u3 p! z6 v
    在未涉及具体的计算时,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便是已计算好的结果了。
    $ e1 e  W: x/ g$ g$ Y上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
    ) J9 i/ V. I4 {' W  c6 t# \& @实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保$ W% }* F9 R5 T: A0 x; i( f
    输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
    % c  A% f# d  P2 n) X从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。# u5 N# X4 F% C

    : u) c, M) N- H, j( j*********************************************************************************************************************************************) U# |/ z6 L0 U# E" k* p

    % x& S5 G9 N; F: }5 c) Ymex 的目的,
    2 ^( I+ x6 [+ \( d8 t  V8 S
    " t9 l' I1 ~3 q6 [; J' k# i通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:$ k3 {/ p0 d$ t! ^
    & E# v5 D9 m# b; z
    1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.2 x/ Y% p0 m/ P3 V
    $ v- R5 J; D. ~6 y" ]( |
    2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.5 Y/ l% q; F; M1 E1 X
    - T( p2 B, ]. p* q/ {
    3、据称可以弥补Matlab硬件设备接口的薄弱环节.6 k% {  {; E/ U  _

    / }; t- o0 n" N1 @, U& x) ?- H* y3 }今天写了第一个使用MEX.. p  C( [% m9 `% q) O9 r

    & \$ C, D8 `+ d5 Z一个简单的对Matlab普通数值矩阵的操作.2 q) b1 T1 g/ u& _5 F' C
    6 |9 Y( C; ]* O% c4 \# H% z
    其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以* w5 I% V4 e  f. z8 P

    . I: C& A/ K. S1 m% q一律用int代替.- {% q4 }7 }; O+ @+ l3 e  F$ Z9 Z9 R3 J0 d& Q
    % t5 G" m4 c) j/ R* k
    #include "mex.h"
    / h- R3 j5 y) o: ?% C$ D#include <iostream>4 J2 |1 M; c. n: y3 ^/ H( W0 r8 b

    : g. p8 |8 ~: l# ^- _void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])% T% W* g. W0 e. M# u, |7 Y
    {. b' C* ~( b, \6 c1 K0 }
    " N  z( L& c4 @% d$ l3 f( w
    int i,j,k;
    7 w* A* r% ~$ W& q. F! _4 ?int index;; I- S8 y( l4 }# s0 i. g$ q5 o/ N
    double* pr=NULL;, d1 o. n5 f* _+ Q* k+ g0 M; \
    double* pi=NULL;
    5 `1 m7 c' @; L8 g0 @& Nint M,N;8 a/ `( i+ `0 l2 K& L+ d; {4 B2 l7 Z
    int ndim;9 d3 L; b% D% ~5 f% z
    int dims[2];. P! {1 c$ F- c, I+ t! H. U
    for (i=0;i<nrhs;i++)
    ; ]7 f4 h# j3 L2 E. j, i$ c& B{
    ( t( I1 P. `; O: t% }6 F9 b% G, B   if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
    ) E. T8 t  G8 p6 S8 Q   {: c6 O5 l- t4 C
        pr=mxGetPr(prhs);. A& K$ V7 A3 Z: F- U" J* \
        pi=mxGetPi(prhs);
    % \2 d7 q, z8 Z6 e" _4 {    M=mxGetM(prhs);% c5 h. |9 v8 Q3 ~: P
        N=mxGetN(prhs);
    ) U; `! w6 N  T9 y* h! E    ndim=mxGetNumberOfDimensions(prhs);
    ; ?$ Z- y& B8 h. S; Q! t' ^5 J( J7 G
        mexPrintf("变量%d:\n",i);3 B$ B1 y# z* S8 c& x6 e
        for (j=0;j<M;j++)
    4 c- [2 A- o. i: P0 y2 s0 q" H! Q) t7 b    {8 K6 A% w8 A. L" z# F7 k
         dims[0]=j;  @- v: e# t: F) {
         for (k=0;k<N;k++)
    / S6 l6 L1 h7 E     {6 V3 A0 f, \; m) }+ a) N; P- F3 ?
          dims[1]=k;
    " A* p3 I4 s3 m      index=mxCalcSingleSubscript(prhs,ndim,dims);
    7 t/ i+ j- Z! N/ g      if (pi==NULL)
    . N9 {$ i/ t' [6 I( P2 r+ N0 i      {% l. Z* q# q1 w
           mexPrintf("%6.2f",pr[index]);7 N; O( @/ P  _& q9 U. n
          }
    3 {( z- p1 K, V5 b0 F4 D) N      else{$ x1 B3 ]! }, s- b; p  i. Q
           mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
    : _/ n! W0 V6 i' l! S" M      }3 i  K! M- o* r2 K- C
         }
    4 N  U: w+ x3 r0 n     mexPrintf("\n");
    $ o; ]% M5 u* j" ^3 u/ j
    & h4 b/ T" h0 [! j- P    }- o$ ~9 b8 E! ]
      
    4 ^$ g2 {; O# U5 K) i- X. Z   }# \+ v6 n  H+ Y4 W! S, j
       else{9 {. z8 v. ~1 `+ X" t1 C( |
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);. ?" }% a& f6 L; t
    }
    - i: S4 c1 {. Q/ I$ j. D6 ]6 K+ s: D# t* n# ^
    # m; w. d. e$ w! `/ b) C+ O
    }
    1 e( y& j, {7 d8 W( F! e8 g  L% _" _! H$ J; \- B8 u3 \
    }( E8 c+ M7 ^0 \

    - B: q' q! j& c5 _- ]Result:
    5 d3 ^+ k. @% H0 @( }
    " Z% [0 C: l& M3 [# O0 z>>mex test.cpp% J+ G+ I1 {* ?9 c+ \) t/ Y
    >> test(a,b,c)
    $ h0 e4 \. h, c% b变量0:" k" P. E: L) W8 X
    0.35 0.62 0.83
    ; u  i) ?' [6 q7 J& x" l1 R0.20 0.47 0.59  R/ ?7 L& f% Y# s; y# k
    0.25 0.35 0.55
    * k0 ]* V# L# s4 b变量1:
    2 e  X5 B9 A" s9 H# R8 E0.92 0.38 0.53 0.572 |7 E* ]: ^0 s  F; B
    0.29 0.57 0.78 0.47: X$ X5 v5 A* [7 q! X- z
    0.76 0.08 0.93 0.01
    / Z7 d  M) u  B1 r+ q" y* Q0 @0.75 0.05 0.13 0.346 i9 w+ J6 ^7 m1 {% E
    变量2:
    $ x2 _" Y- T) Q* A0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j, U  n% U9 @% F
    0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j
    3 i; \$ E4 L0 N4 S0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j; {: O" F0 O! f8 e+ S
    0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j
    ) U. K; b" t. V8 U0 E7 A, H0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j. N# i/ h7 g2 C
    >> help test, d0 i5 a8 X, f) l, W- B
    本程序用于调试mx______函数.
    7 r3 j* w" H& [% E$ R$ Y" ^  ]* o4 Z0 W

    6 @2 v7 O& f, `& p  z2 W6 l本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html
    , Y& ?; r0 Z. m) o4 w8 X1 Y5 m$ B
    9 Z  B) w. o; a' k下面是其附件,内容一样,方便下载 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-14 14:38 , Processed in 0.494654 second(s), 112 queries .

    回顶部