QQ登录

只需要一步,快速开始

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

    ! }) H2 X- n, \2 E7 NMatlab调用c程序
    & J2 V& X- d9 \+ j- M( X文章来源:不详 作者:佚名
    ; J8 x; \% y& D0 T% g4 m
    4 a' U& u4 L9 g" e--------------------------------------------------------------------------------
      \" Z: y3 q6 h* w/ n3 \. ]
    % c7 R% n/ E: T3 h6 `1 O# M该文章讲述了Matlab调用c程序.
    4 w, A: }# y# D6 M$ R 3 v5 Y/ A8 s+ t/ f
    方法:* `& s: m8 ?: ^* {
    第一步:要先在matlab中安装c程序编译器,步骤如下:9 I5 s: {0 }3 I# w2 W; I
    键入命令:mex -setup
    5 s5 u- N+ {" p9 R选择c/c++编译器;. h7 R+ ]- V- X% J9 U$ d% E
    选择c/c++编译器版本;4 |8 @/ b& y* i% u0 s6 ~3 q
    确认。. V, g+ y4 A: Y* @7 h# R
    第二步:键入:mex *.c
    , l2 Z- Q7 A# t4 R- z/ g- \2 o3 x9 c+ W% u% _; J$ K
    *********************************************************************************************************************************************
    6 @- H3 k1 O& ]- @4 ?7 C9 ?5 E, P
    ; Z! V, [3 R  J3 D2 p实例介绍:【转】
    0 B  C$ I. P% Q* Q" _. T4 k# D/ T$ [( p8 c9 @# O7 U
    如果我有一个用C语言写的函数,实现了一个功能,如一个简单的函数:
    ! a+ w9 w3 T: Idouble add(double x, double y) {
    5 b4 W& Y/ Q. Z6 u+ I% v return x + y;
    ! b; Y1 l& r) d! t. c# I; s}$ p9 J; {. ~% E+ }: D/ e
    现在我想要在Matlab中使用它,比如输入:
    + V7 f, E+ h2 e0 u" q5 |>> a = add(1.1, 2.2)
    / f2 Y9 w: K9 F. W7 K3.3000
    5 f- B  U3 J3 ~要得出以上的结果,那应该怎样做呢?
    ; g2 y: r0 e1 b: Z4 w6 u解决方法之一是要通过使用MEX文件,MEX文件使得调用C函数和调用Matlab的内置函数一样方便。MEX文件是由原C代码加上MEX文件专用的接口函数后编译而成的。. E- V! G2 A' X6 @2 l0 b8 \- w* u3 |
    可以这样理解,MEX文件实现了一种接口,它把在Matlab中调用函数时输入的自变量通过特定的接口调入了C函数,得出的结果再通过该接口调回Matlab。该特定接口的操作,包含在mexFunction这个函数中,由使用者具体设定。8 ^6 q' K! S' y9 M
    所以现在我们要写一个包含addmexFunctionC文件,Matlab调用函数,把函数中的自变量(如上例中的1.12.2)传给mexFunction的一个参数,mexFunction把该值传给add,把得出的结果传回给mexFunction的另一个参数,Matlab通过该参数来给出在Matlab语句中调用函数时的输出值(如上例中的a)。; I4 w8 z, [4 }; m" f# v/ M& X
    比如该C文件已写好,名为add.c。那么在Matlab中,输入:
    % @( k- f! k9 i>> mex add.c) p! v! O, x' H+ ^0 K$ S7 f2 u1 v
    就能把add.c编译为MEX文件(编译器的设置使用指令mex -setup),在Windows中,MEX文件类型为mexw32,即现在我们得出add.mexw32文件。现在,我们就可以像调用M函数那样调用MEX文件,如上面说到的例子。所以,通过MEX文件,使用C函数就和使用M函数是一样的了。0 u1 e: ^0 l1 ~$ I6 c
    我们现在来说mexFunction怎样写。
    ; S* F! Z: q  L2 M0 h9 e# ]mexFunction的定义为:! j/ A- w' ?( v7 V
    void mexFunction(
    . M% M5 |# {* h% T* h+ X( Z     int nlhs,4 h$ x0 D, f; g2 C
         mxArray *plhs[],
    2 c- Q: h8 r9 o     int nrhs,
    1 u( ]: Z' M; P* F5 P% w: _/ Y     const mxArray *prhs[]) {
    # _7 ~, Q) [2 b/ ]. E& Q
    / d0 B6 {; o7 r  s% U! o}+ u# J& x5 {( k' X# I; D% v% H
    可以看到,mexFunction是没返回值的,它不是通过返回值把结果传回Matlab的,而是通过对参数plhs的赋值。mexFunction的四个参数皆是说明Matlab调用MEX文件时的具体信息,如这样调用函数时:
    * Y- B; x0 b4 T>> b = 1.1; c = 2.2;- _. a/ |5 }7 Z) a9 m" u( n4 \
    >> a = add(b, c)
    6 l9 w: p, C  n; [mexFunction四个参数的意思为:
    3 M3 S1 ^; x0 }, Y5 Q+ V( Tnlhs = 1,说明调用语句左手面(lhsleft hand side)有一个变量,即a
    $ R7 R3 Q& C" V7 p: Z) ^& Tnrhs = 2,说明调用语句右手面(rhsright hand side)有两个自变量,即bc
    : T# m& B' O6 L- `' G9 ?7 k" Xplhs是一个数组,其内容为指针,该指针指向数据类型mxArray。因为现在左手面只有一个变量,即该数组只有一个指针,plhs[0]指向的结果会赋值给a, L: O  s- V  E5 q
    prhsplhs类似,因为右手面有两个自变量,即该数组有两个指针,prhs[0]指向了bprhs[1]指向了c。要注意prhsconst的指针数组,即不能改变其指向内容。7 j- N9 R2 r. p- h6 s
    因为Matlab最基本的单元为array,无论是什么类型也好,如有double arraycell arraystruct array……所以a,b,c都是arrayb = 1.1便是一个1x1double array。而在C语言中,Matlabarray使用mxArray类型来表示。所以就不难明白为什么plhsprhs都是指向mxArray类型的指针数组。
    , U8 S5 N0 x/ l0 |完整的add.c如下:# M! \. f' S+ u
    // add.c6 [8 _) Y8 B+ j
    #include "mex.h" // 使用MEX文件必须包含的头文件 // 执行具体工作的C函数: x, [# j1 U7 q
    double add(double x, double y) {* }' q5 Q3 Z: J7 j, a
     return x + y;# J& d8 Y$ ?7 ^6 I. L
    } // MEX文件接口函数& v& [4 {: r& u  Z1 N2 H
    void mexFunction(
    * B3 s) E& `- S1 e! } int nlhs,) s1 d% [+ }- s8 V0 ~- J
     mxArray *plhs[],+ F* n7 h  L5 Q. Y# s, h0 X# y2 B
     int nrhs,% W" y6 a: h4 Y, Y8 ]4 \% J7 s2 o8 ~
     const mxArray *prhs[]) {
    2 y! n8 k) }# L0 ] double *a;
    * \3 P9 ^% Y9 l' {7 }  }) O double b, c;
    / B9 v6 T" J8 @ plhs[0] = mxCreateDoubleMatrix(1, 1, mxREAL);
    9 t' O# D/ U  w7 F a = mxGetPr(plhs[0]);8 s8 _* p* X; V7 V  e+ ~2 u" D
     b = *(mxGetPr(prhs[0]));4 a& ^+ w3 K0 z3 u5 }/ k0 ]; L
     c = *(mxGetPr(prhs[1]));
    ) N- u2 {( p4 p5 M4 M$ G/ p: @ *a = add(b, c);, g! r- a8 N3 B3 A( t, |
    } 4 D. v6 v8 g7 X7 k
    mexFunction的内容是什么意思呢?我们知道,如果这样调用函数时:
    ) B6 f1 {" u5 ~" H>> output = add(1.1, 2.2);: S# b- x" ~9 o* l/ j1 d
    在未涉及具体的计算时,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 X+ F# A6 ~' q: ?上面说的一大堆指向这指向那,什么mxArray,初学者肯定都会被弄到头晕眼花了。很抱歉,要搞清楚这些乱糟糟的关系,只有多看多练。# Z6 q: f: m! h  U
    实际上mexFunction是没有这么简单的,我们要对用户的输入自变量的个数和类型进行测试,以确保0 D8 w* ]& t7 K# m$ E" o
    输入正确。如在add函数的例子中,用户输入char array便是一种错误了。+ m6 r+ V) ~4 ^9 e
    从上面的讲述中我们总结出,MEX文件实现了一种接口,把C语言中的计算结果适当地返回给Matlab罢了。当我们已经有用C编写的大型程序时,大可不必在Matlab里重写,只写个接口,做成MEX文件就成了。另外,在Matlab程序中的部份计算瓶颈(如循环),可通过MEX文件用C语言实现,以提高计算速度。  M) z3 P% E- a( c* O  N

    ) }2 l; d/ |  X2 ~* d7 O6 A*********************************************************************************************************************************************
    & n' [* O- ^  m" m3 n8 v3 z$ R! I' l1 ]; i. q8 ~
    mex 的目的,9 K% p& w' t6 @

    ' |* h1 [% N5 ?2 _8 t通过C/C++语言编写代码,Matlab中将其编译成mex文件主要可以做以下几方面的事情:3 _% I% z1 d1 ?5 f
    6 C  X: f2 I' Y; `& t* Y3 u* }- p, i9 @
    1、加快程序的执行速度. Matlabfor上如老牛拉车的速度确实让人抓狂.
      H9 R6 O& T1 ?0 @$ B( {  b) x( Q4 R  `; g6 h; L
    2、将Matlab作为C++的开发调试环境.尤其是有大量数据需要处理时,Matlab观察其中间结果十分方便.
    ( ^) C- |4 @; z6 g3 M$ O/ u% D+ c  w  R( h% E% Q$ `5 t
    3、据称可以弥补Matlab硬件设备接口的薄弱环节., l6 @5 a! s0 h8 i7 E3 P4 I' h, R

    $ Z/ }; d  S4 Z: |% a今天写了第一个使用MEX.5 x8 J3 x1 w1 g1 R' Q

    . ^( X- |3 [8 t" {6 b一个简单的对Matlab普通数值矩阵的操作.
    9 d  m2 _0 F: |1 W
    / E6 V& P4 N- p% A$ }其中Matlab规定的与操作系统版本有关的mwSize,mwIndex, size_t32位系统上其实本质上就是int,所以; D8 ^6 q  n# U% O1 c5 r

    + U8 u' l4 R: A. A% c* @, @9 G+ F一律用int代替./ k# A3 R9 b  D4 G0 v: {7 G. p0 @

    * [! \! E9 w2 E- s8 C; V1 B4 o#include "mex.h"
    + J( k# N$ {' l#include <iostream>: e8 p6 g% X8 M/ j
    ) k: c* g7 o8 |2 x3 v
    void mexFunction(int nlhs,mxArray *plhs[],int nrhs,const mxArray *prhs[])
    / b* ?  |9 v2 \! k; k$ q{! K1 C7 k! |2 D# f8 Y
    + }8 u4 _. K7 C& i) u+ }
    int i,j,k;# R# U7 V  ]+ P
    int index;
    ! u0 I. q3 d2 M& j, z* t' M1 q* |double* pr=NULL;1 d; j$ x& l% ]7 Q# {
    double* pi=NULL;
    % R2 W+ k6 `" T' D6 L: hint M,N;# D- v! `  f$ d% z4 o7 @
    int ndim;5 ^% l" s( `9 H% \
    int dims[2];/ s9 y" R2 J$ Y- y8 I& X
    for (i=0;i<nrhs;i++)
    + e6 N1 C  |) x9 p0 D) t5 S{7 M. o/ y* m+ \" R, w
       if ((mxIsDouble(prhs))&&(mxGetNumberOfDimensions(prhs)==2))
    / W7 {8 D* p7 k   {( I" y& u+ [1 F% s
        pr=mxGetPr(prhs);, \  f( \8 h" V1 x( z
        pi=mxGetPi(prhs);
    / D" h* G0 P' d5 h, C1 o& A  F5 L    M=mxGetM(prhs);+ T/ N/ a) A6 `/ J
        N=mxGetN(prhs);
    / m' W' h0 l. W5 _+ n    ndim=mxGetNumberOfDimensions(prhs);$ T& w( Q) e) s& i" G$ b1 ~

    2 r3 t& G1 k# |" H, g    mexPrintf("变量%d:\n",i);5 \  [* v- L7 C$ I( O
        for (j=0;j<M;j++); ^- Z- N$ ~4 ^( f8 |* f
        {. R7 B. j5 T+ f8 n
         dims[0]=j;
    - Z) Q# q2 f4 G  X( N     for (k=0;k<N;k++)
    ' G, I7 O" c* f. k7 J- A' I     {3 f1 U& ]6 L% |& O, f* ^3 n
          dims[1]=k;. n. M9 C( K3 _" L
          index=mxCalcSingleSubscript(prhs,ndim,dims);: q8 H  J. z; O4 L3 {  t% ~9 ?5 ?
          if (pi==NULL), V) ~& W" X3 I! P4 H) @: A0 Q
          {! a& t& ?4 S! Y1 p# e/ L" b
           mexPrintf("%6.2f",pr[index]);: [0 r2 ?! _$ e
          }; D' [; m# X: Y
          else{8 W* C" l; u/ A) E: M5 R- \
           mexPrintf("%6.2f+ %6.2fj",pr[index],pi[index]);! L7 l8 @5 E6 b. u* U9 N. T
          }
    " b3 j( H. G9 Q$ w7 f1 D- c     }
    . {( ^+ ~1 h9 u9 n4 E     mexPrintf("\n");
    6 O# C$ W; \6 F8 c: l; V6 G! `; Z: s# [+ }* H
        }
    4 K4 q# ?5 c. C8 j4 Y0 y2 v7 ~$ d  , o5 [& e/ b3 Z0 b' _
       }! w) l# }& v# M  _7 s/ A4 I
       else{
    4 X# M% Z2 `3 p2 P: F    mexPrintf("input NUMB %d matrix is not 2 dims&double numerical array\n",i);
    + o. ]! Q2 E, V7 k}
    * h: U8 |0 T9 w: ^& X
    * n. c- ^5 x# x& ^3 ?; N: x
    4 x6 i6 [9 |* A% E& T: ^0 t" b0 W}
    " \9 p' C2 ^- p. P& Y8 S) r, U" _1 j. u& m8 H# F# @! v. _
    }9 N( W3 H9 T  T0 d1 T

    / R" |5 Q/ q- w% z' v) {: hResult:
    ; y3 F" d* _* B3 b+ A2 T+ }3 l5 V2 M2 ?5 P
    >>mex test.cpp
    ; L) E! F6 y4 h, h. F>> test(a,b,c)
    / i1 D5 j5 [; K; B* F! C变量0:0 |1 X$ Q! ]) z5 z* a3 e
    0.35 0.62 0.83; E/ c0 }/ X# K5 c3 R$ ]
    0.20 0.47 0.59
    * V& x' C# c1 m* d% [0.25 0.35 0.55
    " P" v6 d4 ~/ d0 V' l( p6 F变量1:
    / a# N- B/ K% t, P7 z6 O- h0.92 0.38 0.53 0.57
    ' j6 h5 r2 W3 V, H% L0.29 0.57 0.78 0.474 u! I' `8 o2 n* j
    0.76 0.08 0.93 0.01
    9 E/ m  c9 F( m1 c0.75 0.05 0.13 0.345 `" \: @& T/ t; P( k
    变量2:
    * U# u9 c# A1 s* m6 j7 @1 D0.16+   0.87j 0.60+   0.43j 0.45+   0.14j 0.83+   0.85j 0.11+   0.08j
    + h9 c7 W; b& G5 [* Q3 A0.79+   0.08j 0.26+   0.91j 0.08+   0.87j 0.54+   0.62j 0.96+   0.24j  H, ]5 R& x1 Y9 R1 b$ D
    0.31+   0.40j 0.65+   0.18j 0.23+   0.58j 1.00+   0.35j 0.00+   0.12j* s/ i8 Q4 y6 o: a  l. \
    0.53+   0.26j 0.69+   0.26j 0.91+   0.55j 0.08+   0.51j 0.77+   0.18j2 U& _: a1 L; m# |9 F
    0.17+   0.80j 0.75+   0.15j 0.15+   0.14j 0.44+   0.40j 0.82+   0.24j
    9 M5 I( f3 M9 E9 k8 s. w; X! G6 l>> help test
    1 i% t, K5 T* V: ^6 i$ z本程序用于调试mx______函数.% X9 M, c" r, v) e

    - ]5 p' G2 S0 \* @+ ^, _/ s! ^, g
    - `; ~+ _4 N; q本文来自: 高校自动化网(Www.zdh1909.com) 详细出处参考(转载请保留本链接)http://www.zdh1909.com/html/matlab/14744.html: z4 S8 X9 @: f/ Q6 p" M

    ! _; K" @! |8 n) x0 [8 [' z4 M下面是其附件,内容一样,方便下载 Matlab调用c程序.doc (41.5 KB, 下载次数: 10)
    zan
    已有 1 人评分体力 收起 理由
    天海星云 + 5 很不错的,鼓励共享。

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

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

    32

    主题

    50

    听众

    2988

    积分

  • 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-5-25 22:31 , Processed in 0.506785 second(s), 112 queries .

    回顶部