QQ登录

只需要一步,快速开始

 注册地址  找回密码
查看: 4106|回复: 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
    1 R1 U$ m  r/ M0 W" I
    Matlab调用c程序
    5 h  D  |2 s& j2 q文章来源:不详 作者:佚名
    # b4 [( S! B4 z" {  U
    ( x0 Z3 I/ [: K3 ]" i--------------------------------------------------------------------------------5 F. Z8 }0 |) c+ q" {# \, F! c9 E
    3 a0 X; t3 Z6 E0 |$ r% u
    该文章讲述了Matlab调用c程序.
    , g3 U- n: p; z
    3 B1 z# k: S# W$ C5 g方法:
    + C: l) W# d& Z! Q. n% k第一步:要先在matlab中安装c程序编译器,步骤如下:8 P# Y: k) q) ]2 c
    键入命令:mex -setup6 D. t% a: l' A9 l( e. O
    选择c/c++编译器;6 F' f6 E4 G0 U9 F2 X7 o9 j" w
    选择c/c++编译器版本;. z' z$ F" D6 |
    确认。2 r1 k* I6 H: Z- H0 C: t: ]
    第二步:键入:mex *.c- Q% k2 g2 [+ D! E9 m6 n
    3 M& U0 p) e1 U, O! L9 {* Q# \" t
    *********************************************************************************************************************************************
    0 Q: {% ~/ g; c6 x$ [
    ; r. h. a( g$ d% j$ \. S实例介绍:【转】5 H) Y6 U' I' l: y3 \) N

    7 R; S3 O  X5 L如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:6 W: p9 t# ~& N$ {' y& l
    double add(double x, double y) {2 ]9 x$ y5 Z0 H( m7 S6 T
     return x + y;
    : ~0 Y2 N- P/ A+ G}' I) F8 S  E2 O5 T
    现在我想要在Matlab中使用它,比如输入:1 k  n' B/ ^/ @5 N: v. B
    >> a = add(1.1, 2.2)/ |8 E5 b& v, R# e: t6 x9 A
    3.3000
    ' ]3 x9 i3 F7 F% N要得出以上的结果,那应该怎样做呢?' F9 L0 h. i+ ]
    解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。$ K8 u3 d# K4 o
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。
    . ~. \$ p$ X+ [6 y2 _9 E0 ]1 j所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。
    ! n) g$ ]# I; U- t: I! E比如该C文件已写好,名为add.c。那么在Matlab中,输入:; B$ o1 [2 c& m) n: m- h8 n. s
    >> mex add.c
    3 h+ ^, u% K  l就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。
    9 W% R7 r1 a' A$ l2 ]我们现在来说mexFunction怎样写。" `0 D' n+ c  G" d
    mexFunction的定义为:
    4 l8 z8 a* y& X  Qvoid mexFunction(: a4 J% n5 }2 K: |- X* n. J: N9 r
         int nlhs,
    9 w+ P# s* Y) V5 c     mxArray *plhs[],5 B( v" X" K3 @
         int nrhs,$ C% X1 @1 l" G8 e" p" x& e
         const mxArray *prhs[]) {5 i8 X! {4 t5 E) _2 i

    8 n/ K+ z1 c/ W0 B}1 g. D" i7 N( t6 o" G* U- c8 r
    可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
    7 K+ T  h! y  m# ?2 I1 R9 x>> b = 1.1; c = 2.2;
    * I8 ^! K# @! J- P, X>> a = add(b, c)
    + Y, H9 P& F3 k3 [/ P8 ymexFunction四个参数的意思为:, C; U: ~( p2 f( A) y# I
    nlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a
    ) s9 X5 T+ H( j3 e! _nrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc7 h4 D* j5 S8 H7 }0 F* m, N0 n
    plhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a' B2 D; E" Q8 w! ?
    prhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。2 T* r' v% j0 X& Q7 A& \
    因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。* D- B4 Z& |3 h1 [! {
    完整的add.c如下:
    8 N; t! W8 n; o9 o// add.c5 X" g8 b  }! H7 X0 g# B6 I" r# U
    #include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数) T# m0 a, W! f' U; X
    double add(double x, double y) {
    + H' Q: k$ |# b( { return x + y;
    * u6 V! f! J  q- I! ?} // MEX文件接口函数# b  Y1 N! I4 S5 a& F
    void mexFunction(
    / u  m, k9 g5 z7 z, U; W) n9 V" H int nlhs,
    - M2 D1 i" W5 Y5 P8 _! t, U mxArray *plhs[],
    8 S4 m5 @3 z; n' | int nrhs,
    5 H7 A( V3 S) g+ B. C const mxArray *prhs[]) {/ s  D; A$ p+ r/ K+ q  M% r# T8 w
     double *a;, N* ?7 K" c" k- }- W
     double b, c;- r; l2 x* {, K1 |6 V8 `! C
     plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    9 m: g2 w; ~5 X! ]: H a = mxGetPr(plhs[0]);: l- r! j5 P! \" t
     b = *(mxGetPr(prhs[0]));' c' h8 T) _( g% G- I; m
     c = *(mxGetPr(prhs[1]));
    ' ~- S4 c( Y% \0 E, _" D! m% ^# ?9 s *a = add(b, c);( N4 m5 `9 I9 {) w0 ]
    } " D( K! }$ Q- V$ O* C
    mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    ; q7 z1 o" P  c4 k0 O- e) ~>> output = add(1.1, 2.2);: ]0 g1 a6 O% c/ I# b
    在未涉及具体的计算时,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便是已计算好的结果了。4 {0 K1 D  `4 C" P7 L+ Z
    上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。
    6 `& c' J& R+ j+ _实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保
      l: i; C0 S2 G# L3 K0 \! Q输入正确。如在add函数的例子中,用户输入char array便是一种错误了。
    7 [$ O& T# s. `" Y  f" n从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。
    ' y6 x! }+ O' F( e; F. R1 w" J; l; i# X8 W5 Y% j
    *********************************************************************************************************************************************. U+ ]! b6 S. L

    9 J3 }$ M' C. amex 的目的,- |; q, E1 m1 y- N

    2 V5 ^- C$ {+ o通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:
    3 \- m, ?6 Q- {& s$ @
    ! q$ N/ _, ^- a# D* u# G5 n( `/ n1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.
    / s: I, N" a1 @- n# i3 p* n! D% H
    8 q' ]3 R: b; G4 p) T: S2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.
      X/ R  j2 b& p0 f. @5 ~1 \3 @5 c& {9 M$ c( M. x8 g
    3、据称可以弥补Matlab硬件设备接口的薄弱环节./ t* z: s' M1 a/ U$ n! l9 B  z5 E

    . _' J$ \/ L0 n$ C( |. f. {8 n6 X今天写了第一个使用MEX.
    , m  T: K- p3 ]+ s( k4 W/ m- C2 U7 K0 S
    一个简单的对Matlab普通数值矩阵的操作.
    ( V, T( [0 P3 p' r3 q
    ) ~7 e7 `6 Z% G9 b; c% p其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以! @7 ~: ]( q+ Z0 Z7 ^: q% b

    7 U2 S- S; e; E+ {5 o4 j+ W一律用int代替.
    7 d5 e! y, v" A) U/ {; G! C% c6 ?% V8 U: s" M3 w
    #include "mex.h"
    $ h- b. O) o6 ^0 h- y#include <iostream>
    9 R% e) ?( R6 u. E& k4 K, p
    7 j! h' M( H: \6 L3 Lvoid mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
    7 O# w. q8 w5 s5 i& H{
    ( n) c+ S7 X( Q' F
    % _1 A7 p6 W2 `: I3 n! \int i,j,k;; p( @0 v' O- v) |0 G
    int index;
    * |( g2 f& k4 b+ c9 H6 X# h3 Kdouble* pr=NULL;  G% o" ]/ M  ]: b/ W
    double* pi=NULL;; z+ Q3 b! u6 P" a/ v+ U
    int M,N;. v7 V* x& N" _5 B- J
    int ndim;
    & a3 p4 d% T  K& `& f' fint dims[2];
    : \1 U) o% O2 J/ n5 R" F. Cfor (i=0;i<nrhs;i++)
    4 u2 n9 E: [7 X5 y{
    3 n' ^0 K$ U6 g1 n& q7 R   if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2)): j; B4 I; W! t( j2 Q
       {
    ) W/ O2 M  C6 G  V5 ^! X: T! Q    pr=mxGetPr(prhs);
    4 {+ U, P/ {1 V! D    pi=mxGetPi(prhs);
    , {  X* n7 D5 s+ u" \& m9 d0 E    M=mxGetM(prhs);
    3 }1 W% H6 ~& D# T1 H    N=mxGetN(prhs);+ B3 d4 }1 q' ]3 v
        ndim=mxGetNumberOfDimensions(prhs);
    1 [7 t  L) b6 K0 b# V* N7 V5 P6 C! Q! B
        mexPrintf("变量%d:\n",i);
    / C! W3 f* l  G2 l) ?! |. Y    for (j=0;j<M;j++)' \; S- O1 @- i. }
        {3 V% V- ~* N5 v8 Q3 n$ Q4 ?, z
         dims[0]=j;* u; P' Q' N$ L1 u% m! ^
         for (k=0;k<N;k++)
    & E' P% W0 R( K, d     {
    9 x1 n3 s5 E/ T      dims[1]=k;
    ) a0 ?" V+ \1 y4 @, T2 b1 E      index=mxCalcSingleSubscript(prhs,ndim,dims);& C. }: p# p; z) A
          if (pi==NULL)' Z, f1 A' l8 H& w% b- x
          {% v7 y4 o+ K+ F  |' J: P/ X% U  n$ s
           mexPrintf("%6.2f",pr[index]);5 {% ]! g' G; t
          }% l& s+ U; ~9 F
          else{
    ! T$ H) a" B, ]) D) A" o       mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);
    % k! S! [# A2 k  o$ R      }) j! B3 O" `5 W6 q3 J3 Z, `
         }
    4 i9 l5 K7 Z  {5 e7 ?     mexPrintf("\n");# }6 I/ _+ [/ B
    8 B- @9 k5 i0 v! V; [- U6 A9 @4 s9 e
        }" q7 i9 V0 {! \# S- S
      " h: x0 w' B+ c: y
       }8 k- k7 [$ F# S% p7 Q
       else{" n, _7 M, Q( V9 m' D+ t0 i( W
        mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
    6 A: S/ m3 p% W}
      U4 J! X  j- Z3 n+ z4 ]
    ' l9 U  S) Z8 C0 n/ o0 W9 Z
    # y: z# Y# h" g( U}3 M2 Q( m! m8 B6 M

    " h9 T% _, g2 i! s}
    / H% H4 t; a  n1 I- H6 c( Z" W. z7 E% G# M3 |/ T0 I! b1 F
    Result:; U& c: G+ K& V4 a

    + {- d, Z% g1 `' b; ]9 i2 {! v>>mex test.cpp/ ?$ Y  ~: o8 ^
    >> test(a,b,c)6 [8 d, o9 k  n" F
    变量0:
    0 W5 d; B# U( X8 L/ e# t9 n0.35 0.62 0.83% P% z% n5 M( D- k1 ]& K
    0.20 0.47 0.59
    ) r: i. v0 g0 |: c0 s2 X6 l1 J0.25 0.35 0.55
    ( n. I. }* h! Y6 P( m. N变量1:" T. i) C9 q) I; w
    0.92 0.38 0.53 0.570 }# V8 t7 I% l
    0.29 0.57 0.78 0.47
    $ Y$ p1 j2 B# x: ~7 @: d: l0.76 0.08 0.93 0.01
    1 ^8 l, \" V, B  m$ M0.75 0.05 0.13 0.34+ W( F+ J$ W% H$ P
    变量2:. N8 y* y- E5 z$ s5 K9 P0 S
    0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j
    * l7 f6 p: ]3 C% E# D0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j4 q0 T5 D6 A6 s8 y7 e* s# T3 u
    0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j. w$ ?, G4 ]" ^  p% w8 w: P4 l
    0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j
    : C0 g$ H" K; I  y0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j
    + t7 {: k  e' w- Y4 r>> help test
    5 J; r( v/ O) w5 @  T5 K本程序用于调试mx______函数.% j& w; i5 m0 h' j  \
    0 R6 b) a  i" [3 ?6 Q! `: S

    0 |2 M; d, [+ V; @本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html3 x# W6 k. l1 t5 j# j7 T

      O$ t3 s* c, D0 l2 o$ W8 x1 t下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

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

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

    32

    主题

    50

    听众

    2957

    积分

  • 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, 2025-8-7 03:47 , Processed in 0.777026 second(s), 112 queries .

    回顶部