QQ登录

只需要一步,快速开始

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

    , |) a1 u6 k% r5 h/ eMatlab调用c程序
    2 h5 C! o. _! V% v( h文章来源:不详 作者:佚名
    9 X( V" _+ o" F5 `! b3 I! ~6 o; n3 l% l% v1 ]
    --------------------------------------------------------------------------------# v2 b9 t" A' Y& w1 @

    4 T# j6 |% q$ |4 Y, O该文章讲述了Matlab调用c程序.2 U5 p' @8 c- S; Q" s/ Y) O/ Z& E
    9 m% i) K, P$ m% k6 C4 K
    方法:
    ! Q4 b6 }" j5 q; f: q" k第一步:要先在matlab中安装c程序编译器,步骤如下:& a1 b# R9 G, y
    键入命令:mex -setup
    , |3 k; m6 f) w选择c/c++编译器;! M5 q. Y* J! }+ Q8 I- a
    选择c/c++编译器版本;' m* o* u- _* k! X  Q
    确认。3 Q3 [) r  s# q
    第二步:键入:mex *.c
    , C% k2 X0 N' v5 x. I  e1 W: q+ {, j& w& q/ z' P
    *********************************************************************************************************************************************) [  q  [; q' I9 S

    0 W0 s0 X# [$ f/ u/ ]9 N实例介绍:【转】- f' d4 R/ F! F: u- M6 I' D
    4 i& H$ o$ d! b! \/ w. y: f
    如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:* f; q' X# R, m& u9 j# y7 K+ S
    double add(double x, double y) {
    6 X5 Q  R8 m8 z' B return x + y;
    % v% A9 [% L- P7 f' @5 h/ z}
    , K; g8 ]& H' F) |* q1 k现在我想要在Matlab中使用它,比如输入:
    3 |3 h+ S# C, Q: c/ @>> a = add(1.1, 2.2). K; X- P4 g: w  q" }) c2 f
    3.3000- Q/ C2 l$ ]' k0 B
    要得出以上的结果,那应该怎样做呢?
    " }0 G! x/ f7 \解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。" @5 ]: o0 O5 W5 T
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。0 s! o8 u( q) J" z" d# F
    所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。: ^$ i$ D1 M6 j/ s
    比如该C文件已写好,名为add.c。那么在Matlab中,输入:1 B: m9 J, c! b3 K7 q0 H
    >> mex add.c  w8 f5 `: w6 Q. K
    就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
    $ y  ~/ [5 m5 j' b我们现在来说mexFunction怎样写。
    . A5 k& N! z7 p, l2 D. d0 kmexFunction的定义为:
    3 ^; ]2 Y8 ^0 N* E, b1 }8 f7 @( A( xvoid mexFunction(/ M/ s) {6 h: [$ y+ N- b7 q+ y) ?
         int nlhs,- J( H9 H! \! K+ y$ V
         mxArray *plhs[],1 P6 B* z5 A0 ^5 k& Z. @5 L
         int nrhs,+ e2 I5 m" f5 q" u" V4 L
         const mxArray *prhs[]) {
    & t6 m' H. |$ K( [" O) a& u6 |1 a7 E6 Z8 E
    }5 t& e$ n6 e1 J. Y( L2 {/ a2 y
    可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:5 p+ H& k) C) {
    >> b = 1.1; c = 2.2;* k# k- m( v! f' I( |' S7 n
    >> a = add(b, c): Z" u5 r# ?. j: m5 ?7 A8 m2 V
    mexFunction四个参数的意思为:& T2 Q1 n* L$ o: |: O
    nlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a
    # A3 Z, B( X) o# t* ]nrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc
    ' ?: K$ e% t$ Y; w: \( g; zplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a6 I5 g' n* f  a0 N1 z2 @$ n# D
    prhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。2 O) @, R2 r4 D
    因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。
    6 e1 @! _. M  h9 X8 B完整的add.c如下:+ ?! T$ c# @5 D: l
    // add.c
    # E1 T3 m6 q7 f- d/ L* ?& L#include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数/ B$ U: z5 Q! ]+ d
    double add(double x, double y) {$ H! a3 e% N# E: e, ~
     return x + y;
    8 N2 \9 k+ C$ {" y} // MEX文件接口函数" @+ w8 ^8 v$ q* {* O+ j, x
    void mexFunction(
    / p0 h3 y! o& R; v int nlhs,
    ' Z2 ], F( `5 u( Y9 p; i mxArray *plhs[],3 K' i  u7 Q4 d9 B2 b' X8 g
     int nrhs,
    ! v$ r/ J  Q8 Q+ ]! k% I- m const mxArray *prhs[]) {6 l8 q8 e2 ]  a& x" g+ F( Z& e* f) |
     double *a;
    $ x) L8 L, d. v# W double b, c;
    ; \9 m1 E3 v/ R, E  x/ N% p( G plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    " ]* \4 ?5 ~2 S) v7 Y a = mxGetPr(plhs[0]);
    ' `+ X- E- ?8 D  I+ A2 s b = *(mxGetPr(prhs[0]));
    $ I; y6 i% [" Y* l: e c = *(mxGetPr(prhs[1]));
    6 G+ A  L- L6 a4 W *a = add(b, c);3 D) K) |/ k0 i) f1 w+ @
    } 1 \- R( c! G' m
    mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:. ~$ }- P) F. V& s: E- b
    >> output = add(1.1, 2.2);, q6 ], G* M) R6 ~* 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便是已计算好的结果了。
    5 W6 I) V5 i8 U  ~& u+ W: M上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。& m' d. r0 K! h1 _" v# `
    实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
    : e  D5 e" e: \1 N# i输入正确。如在add函数的例子中,用户输入char array便是一种错误了。5 h9 {* U+ e0 T3 A3 x# `0 \
    从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
    / B3 C/ |6 q, s. c5 j, V# u2 H2 Y! q) S% _6 a
    *********************************************************************************************************************************************
    7 h7 l! I2 y- x) J. j6 H) {9 ^3 S, ?1 C+ Y7 Y, A& Z4 C) T6 u
    mex 的目的,  G. E* p5 X, I7 c7 G- m! @

    7 u, j1 V1 k- z7 g$ I2 E  P2 D0 O6 i$ J: r通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:
    " G# W9 d- v. g! z3 x5 Z
    0 [: U; o8 y8 M9 d8 b3 |9 c1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.
    2 q+ V( x5 M2 i: j
    9 w/ }7 O1 q# X4 ?$ E2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.1 n0 v1 _7 `3 e3 B  Z/ F6 L

    " G) f3 o/ g' [: x; k+ [) ]+ g3、据称可以弥补Matlab硬件设备接口的薄弱环节.7 O$ y' j- s% [8 ]7 L
    2 m, M! h+ {: ~& }# t6 |8 Z
    今天写了第一个使用MEX.
    % s* E' @' g! n1 y
    - D# \2 F; y: _* z! R2 {: R一个简单的对Matlab普通数值矩阵的操作.
    ' T; e" o7 w) I$ Z- k* ?9 O6 F' y; O1 l( [5 ^- A
    其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以
    $ h1 s) v# {& w$ T' L' h9 v& _
    % v1 c: q' X4 f一律用int代替.. T% n$ ^8 j9 i9 h6 N2 t/ X; k

    " p) i1 N. X- V9 a! U2 V#include "mex.h"% y4 g: h# d0 g0 S
    #include <iostream>2 ~+ ?; \2 Q( r9 j+ e! E

    + n& `0 ^, y2 wvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])# J, A0 ?9 [: w: R4 s+ j
    {! G$ A. q, f) I* U, H* b

    3 W& s/ B9 g0 R: R( [int i,j,k;
    - |& O% ~; n; d2 s+ [int index;' E% T% H/ W+ q( G
    double* pr=NULL;
    + \1 E) [& @' C7 ~double* pi=NULL;
    / z7 h& g" n$ C& A( U, Q5 x) `int M,N;
    7 q( }$ Z) d" p8 @# oint ndim;' m6 p( @/ w3 ]( d5 p
    int dims[2];
    9 W3 g. M2 \/ t: G& R0 [for (i=0;i<nrhs;i++); @9 O2 L5 O' h: D
    {
    / K+ m5 ]/ ]1 \# Y: `" q3 m  [   if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
    3 O5 B" v: K- I   {( J; M+ F2 v0 Z6 I. K
        pr=mxGetPr(prhs);
    / W  `& u+ Z* ?% S6 g    pi=mxGetPi(prhs);5 z( _0 K5 H5 y5 E9 l! O3 \
        M=mxGetM(prhs);& v; Y) c$ [. D: ~
        N=mxGetN(prhs);
    . n4 {8 f3 X3 @4 d    ndim=mxGetNumberOfDimensions(prhs);
    7 N6 R. V3 w7 W9 x; z8 D
    6 M2 p8 W! [4 z. |    mexPrintf("变量%d:\n",i);
    # d. r5 u1 H& p9 A/ R    for (j=0;j<M;j++)
    2 T9 c8 [; ~/ e. M' f/ z7 C    {5 X7 B1 c% O( |) I( p: V* H: \
         dims[0]=j;
    1 g: N, `5 Y5 U: ]     for (k=0;k<N;k++)  r% k& @6 l! i% h# b' L* X  s
         {
    + m  r. i$ F0 |      dims[1]=k;
    6 k/ Y; H! J. Z3 w! j! c" g, b      index=mxCalcSingleSubscript(prhs,ndim,dims);
    6 C$ S7 E" q5 c, S8 M5 @      if (pi==NULL)0 Y6 Q2 `! Y5 H" M$ l
          {
      N* z) L4 u& J1 g; @# _" [       mexPrintf("%6.2f",pr[index]);. E1 s, S; `* D* e
          }/ m- C. ?: B  R
          else{, z! F) ]1 Z/ G' y( _: @6 c
           mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);. K6 q( F" h2 |# U: W7 K
          }5 G- e6 G4 @3 p2 }; L$ R8 z' y* M
         }
    2 @% Q; {3 h' S& H$ D     mexPrintf("\n");1 P7 ^, W4 w- w* S3 @

    2 `; v2 E& ]0 S' T# W    }
    5 g0 V9 `* h* L* f8 f+ M1 R  
    ; q6 Q( Q0 b' q  g  u/ f6 n   }
    5 I5 {. Q4 j3 p- E' A6 D   else{3 h( k& d2 J, l" s2 R* Y/ m
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);4 \7 r2 r$ H3 v, O* Y/ x0 o
    }
    # z0 S: j6 T6 Q* o7 T, Y3 v! E; n2 N5 [$ i
    * A+ Q0 K) _# ~
    }
    + T% l8 X7 G. L. Y  Z  ^' `! x9 W$ ?2 n4 v
    }
    * l5 n& e( e- w, Z6 z
    0 @4 H8 l, |' j7 L" N4 U1 OResult:
    ' F  z# f$ _( F6 x
    4 }' G& {: _, L! q>>mex test.cpp8 ~; O1 O2 K3 _3 `# ]1 o
    >> test(a,b,c)" J# ?3 J0 Q3 p% \/ {
    变量0:/ i3 t/ Z: Z# P5 d
    0.35 0.62 0.83
    : z/ f  m: C8 k3 x0.20 0.47 0.599 ~# T& D5 d9 c. w5 H* ~  k$ B% ?
    0.25 0.35 0.55
    3 _' {+ T1 @! F8 P; n; M& E# e变量1:% ^2 z; V; h; o6 ^/ @& N% Q$ H
    0.92 0.38 0.53 0.578 s" s: E" z2 l& N9 {- v
    0.29 0.57 0.78 0.47" Q5 i+ e  t7 [  R: j: W$ D, e
    0.76 0.08 0.93 0.01
    ; Q1 g2 V9 \- |  s5 w8 q0.75 0.05 0.13 0.34: a' Z7 U7 j( c; \
    变量2:' l% d7 S, \8 U$ Q0 ?; P- j
    0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j8 |1 H6 x6 v7 e  x9 r  f
    0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j% c: N4 A& h# v3 P2 K
    0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j
      N/ @6 l. H- N6 |+ X( k0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j0 B4 I1 l* V- C4 m
    0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j
    & c; L6 @( x4 c, D% ]+ N; H>> help test
    - M# }* i6 y, X本程序用于调试mx______函数.
    + b+ n+ i5 J1 A! g1 [; T: l9 z7 s! O: n

    / o1 B4 f4 D  V3 N+ a1 u本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html- T/ V7 t% \6 r' X/ f2 }# V' w$ i2 C

    # u  N8 m& X# Z% M) b$ w下面是其附件,内容一样,方便下载 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-8-24 02:21 , Processed in 0.744598 second(s), 111 queries .

    回顶部